【问题标题】:JS scope chain, variable scope in an object functionJS作用域链,对象函数中的变量作用域
【发布时间】:2014-10-01 08:33:00
【问题描述】:

我正在测试一些代码,只是为了更好地理解 JS 中的变量作用域链。 我设置了 2 个类似的对象构造函数,其中包含一个从前一个作用域调用变量的函数。 我得到的结果出乎我的理解。

var name = "Outter!";
var o = new function () {
                  this.name = "Jill";
                  this.age = 23;
                  this.func = function () {
                                 console.log(name);
                              }
             }
//output to console for: o.func()// Outter!

据我了解,我没想到会有这样的结果。由于 console.log(name) 试图访问 name 并且 name 在前一个作用域(o 对象的作用域)中,因此在到上层作用域的链路径之后,遇到的第一个 name 变量是 o 对象中的变量。相反,全局范围名称变量是引用。基本上我期待的结果是“吉尔”。

怎么会?

是否应该将 console.log(name) 的调用视为对 console.log(window.name) 的调用?

显然,如果我使用 console.log(this.name),Jill 将是结果,但这不是我想要的,我想知道为什么“名称”不起作用。

【问题讨论】:

  • this.name 使它成为函数的属性,而不是变量。所以它与作用域链无关。您定义的 only 名称变量是 Outter。
  • 此外,您也不应该*在那里使用new,您只需要 var o = function () { //...
  • @chiliNUT 那么他需要使用o().func()
  • @Barmar: (new o).func(),而不是。
  • 他只是将这两种操作合二为一。您可以对值为函数的变量执行任何操作,也可以使用匿名函数本身完成。

标签: javascript function object scope this


【解决方案1】:

this.name = "Jill" 没有声明名为name 的变量。相反,它在对象实例(由new 运算符创建)上定义了一个名为name 的键,并将其值设置为Jill

如果您想要您的预期结果,请将console.log(name) 更改为console.log(this.name) 或将this.name = "Jill" 更改为var name = "Jill"

【讨论】:

  • this.name 也不起作用,因为 this 没有保存在闭包中。
  • @Barmer 它会起作用的。当您按原样在构造函数中分配方法时,上下文是绑定的。见:jsfiddle.net/jmeyers91/pn8Lk757
最近更新 更多