为什么IIFE的这个变量是指全球范围?

时间:2015-04-05 22:38:54

标签: 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);
        }());
    }
};

输出:

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

我理解这是因为IIFE this指的是全球范围,而不是myObject。但为什么它涉及全球范围? IIFE的this变量如何引用全局范围?

2 个答案:

答案 0 :(得分:3)

因为这就是JS功能的工作方式。如果您未隐式(通过object.method()语法)或明确(通过.call.apply.bind)设置this的值,则默认为全局对象,除非你处于严格模式。

因此,如果您使用IIFE并使用.call,将其传递给另一个对象,则会将该对象作为this值。

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

答案 1 :(得分:2)

Javascript中的任何函数调用都会根据函数的调用方式重置this的值。 IIFE就是这样一个函数调用。

因此,如果您不以任何特殊方式调用该函数,this的值将在浏览器中以常规模式设置为windowundefined in严格模式。这就是Javascript在进行正常函数调用时处理this的方式。

令许多人感到惊讶的是,没有"保留"在Javascript中调用函数时this的当前值。如果你想控制它,你必须以特定的方式调用它来设置this的值。

在您的代码中,您可以使用this与IIFE一起保留.call()的值,如下所示:

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);
        }).call(this);
    }
};

工作演示:http://jsfiddle.net/jfriend00/66cL4zt5/

有关this设置的所有方式的摘要,请参见this reference