为什么匿名函数没有拿起包含范围的这个对象?

时间:2015-08-11 15:04:34

标签: javascript

我在闭包的教科书中看到了下面的代码:

var name = "The Window";

var object = {
  name: "My Object",
  getNameFunc: function () {
    return function () {
      return this.name;
    };
  }
};

alert(object.getNameFunc()()); // "The Window"

详细解释为什么内部函数中的this对象无法访问对象作用域而是访问全局作用域可能会有很大的帮助。

感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

将其分解为单独的函数调用。而不是

 object.getNameFunc()()

让我们打破它,调用第一个函数,然后调用它的结果。

 var theFunc = object.getNameFunc(); // invocation 1
 theFunc();   // invocation 2

在调用1中我们调用getNameFunc(),我们指定一个上下文(我们之前有一些东西。)所以在这个调用中“this”有一个指定的值, object

在第二种情况下,我们调用函数“bare”,没有指定的上下文,所以我们有全局上下文。

答案 1 :(得分:0)

getNameFunc()中,this指的是object。它返回一个绑定到上下文的函数,只返回到包含范围。上下文(this指的是)继承(虽然范围是)。

内部函数在其中定义的上下文中,尽管它们确实继承了它们所定义的范围。

解决此问题的一种方法是将.bind()返回的函数添加到上下文中:

getNameFunc: function () {
  return function () {
    return this.name;
  }.bind(this);
}

答案 2 :(得分:0)

在Javascript中,每个函数调用都会导致设置一个新值this,如果它只是一个普通函数调用,那么this将被设置为全局对象(即{ {1}}在浏览器中)或window(如果在严格模式下运行)。这就是为你而发生的事情。在这一行:

undefined

object.getNameFunc()() 进行第一个方法调用并返回内部匿名函数。然后,最后一个object.getNameFunc()只是该函数的常规函数​​调用,并且常规函数调用导致()被设置为全局对象(在您的情况下为this)。任何普通函数调用都会将window的值重置为thiswindow。这就是Javascript的工作原理。

这是一个简单的演示,向您展示如何重置undefined

有关控制this值的五种方式,请参阅this answer

您可以通过在父函数中保存this的值或使用其中一种方法明确控制this的值来以多种方式解决此问题。

要理解的一个更简单的机制是只在父函数中保存所需的值:

this

或者,您可以使用var myName = "The Window"; var object = { myName: "My Object", getNameFunc: function () { var self = this; return function () { return self.myName; }; } }; document.write(object.getNameFunc()()); // "My Object"

.bind()

仅供参考,我将您的变量名称更改为var myName = "The Window"; var object = { myName: "My Object", getNameFunc: function () { return function () { return this.myName; }.bind(this); } }; document.write(object.getNameFunc()()); // "My Object",因此在跟踪浏览器环境中已存在的myName内容时,不会有任何混淆。