为什么匿名函数会丢失对象范围?

alk*_*ows 1 javascript

匿名函数/闭包是否应该保留创建它的对象的范围?

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();
Run Code Online (Sandbox Code Playgroud)

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

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()();
Run Code Online (Sandbox Code Playgroud)

//输出

outer func:  this.foo = bar
outer func:  self.foo = bar
inner func:  this.foo = undefined
inner func:  self.foo = bar
Run Code Online (Sandbox Code Playgroud)

Jos*_*eam 6

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

你可以这样做:

(function() {
    console.log("inner func:  this.foo = " + this.foo);
    console.log("inner func:  self.foo = " + self.foo);
}).call(this);
Run Code Online (Sandbox Code Playgroud)

那是因为你实际上是在调用这个函数.如果您传入回调,则可以Function.prototype.bind改为使用.

如果您正在使用ECMAScript6,则可以使用箭头函数来保留匿名回调的上下文:

(() => {
  // `this` retains the context of its parent context
});
Run Code Online (Sandbox Code Playgroud)