2015-12-03 172 views
1

匿名函数/闭包应该保留创建它的对象的范围吗?为什么匿名函数会丢失对象范围?

var myObject = { 
foo: "bar", 
func: function() { 
    var self = this; 
    console.log("outer func: this.foo = " + this.foo); 
    console.log("outer func: self.foo = " + self.foo); 
    (function() { 
     console.log("inner func: this.foo = " + this.foo); 
     console.log("inner func: self.foo = " + self.foo); 
    }()); 
} 
}; 
myObject.func(); 

这种方式产生相同的结果。

var myObject = { 
    foo: "bar", 
    func: function() { 
     var self = this; 
     console.log("outer func: this.foo = " + this.foo); 
     console.log("outer func: self.foo = " + self.foo); 
     return function() { 
      console.log("inner func: this.foo = " + this.foo); 
      console.log("inner func: self.foo = " + self.foo); 
     }; 
    } 
}; 
myObject.func()(); 

//输出

outer func: this.foo = bar 
outer func: self.foo = bar 
inner func: this.foo = undefined 
inner func: self.foo = bar 
+0

人们似乎不仅仅是它“这种”基于@Josh Beam的答案。 – Vivek

回答

6

这只是JavaScript的(特别是ECMAScript5)的核心理念。匿名函数,特别是在闭包中,不保留上下文。

你可以做这样的事情:

(function() { 
    console.log("inner func: this.foo = " + this.foo); 
    console.log("inner func: self.foo = " + self.foo); 
}).call(this); 

那是因为你实际上调用该函数。如果您传递回调,则可以使用Function.prototype.bind代替。

如果您使用ECMAScript6,您可以使用方向起着保持匿名回调的背景下:

(() => { 
    // `this` retains the context of its parent context 
}); 
+0

谢谢乔希。在玩了一下这个概念之后,我现在明白了。你有没有参考资料,我可以深入研究这个问题。 – alknows

+0

@alknows没问题,很高兴这很有帮助:)这是我很久以前阅读的一篇文章,我认为它有一些体面的内容:http://javascriptissexy.com/understand-javascripts-this-with-clarity-and - 主 - 它/。另外,我建议阅读完整链接的答案中的Function.prototype.bind页面,并查看解释箭头函数的链接:https://developer.mozilla.org/en-US/docs /网络/的JavaScript /参考/函数/ Arrow_functions。如果您需要其他资源,请告知我,我很乐意为您提供帮助! –