You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:08:57