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

How come IIFE's this variable refers to the global scope?

本文关键字:全局 范围 IIFE 为什么 变量      更新时间:2023-09-26

我有以下代码:

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变量指的是全局范围?

因为这就是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"});

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

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

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

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

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的所有方法的摘要,请参阅此参考。