JavaScript中constructor与this的疑问:无this为何能访问变量?
为什么两个示例中
name的访问结果不同? 嘿,这个问题确实挺容易绕晕人的,核心原因在于两个例子里的name所处的作用域完全不一样,咱们来慢慢拆解清楚:
第一个示例:闭包捕获了构造函数的参数
先看你的第一个代码片段:
function Person(name) { this.name=name; this.go = function() { console.log("My name is " + name); } } let person = new Person("Peter"); person.go();
这里的关键是闭包的作用:
go函数是在Person构造函数的内部定义的,而Person的参数name属于构造函数的局部作用域变量。- 当
go函数被创建时,它会形成一个闭包,保留对外部作用域(也就是Person函数的作用域)的引用。 - 当你调用
person.go()时,JS引擎会先在go自身的局部作用域找name,找不到就顺着作用域链往上找,最终找到构造函数里的name参数,所以能正常输出结果。
简单说:这个name和this没关系,它是被闭包“抓”住的构造函数参数。
第二个示例:没有闭包,直接访问外层作用域
再看第二个代码片段:
var person = { name: "Peter", go: function() { console.log("My name is " + name); } };
这里的逻辑完全不同:
go函数是定义在全局(或者你当前的外层作用域)中的,它的作用域链里并不包含person对象的属性。- 当你调用
person.go()时,JS引擎找name的顺序是:先找go自己的局部变量→再找外层作用域(比如全局),但全局里并没有定义name,所以会抛出ReferenceError。 - 而用
this.name能正常运行,是因为当你通过person.go()调用函数时,函数内部的this会指向调用它的对象(也就是person),这样就能访问到对象的name属性了。
总结一下核心差异
- 第一个例子里的
name是构造函数的局部变量,被内部的go函数通过闭包捕获,不需要this就能访问。 - 第二个例子里的
go函数没有闭包可以依赖,直接访问name会去外层作用域查找,而不是对象的属性,所以必须用this来指向当前对象的属性。
内容的提问来源于stack exchange,提问作者AntonBoarf
相关产品推荐
相关产品推荐

