ChatGPT解决这个技术问题 Extra ChatGPT

为什么在使用严格时未定义匿名函数中的“this”?

为什么在严格模式下使用javascript时匿名函数中未定义?我理解为什么这可能有意义,但我找不到任何具体的答案。

例子:

(function () {
    "use strict";

    this.foo = "bar"; // *this* is undefined, why?
}());

在小提琴中进行测试:http://jsfiddle.net/Pyr5g/1/ 检查记录器(萤火虫)。

请注意,这与匿名函数无关,而是调用方法。请参阅 this modified fiddle(查看控制台日志)。
@Phrogz:这可能是一些混乱的来源。感谢您指出了这一点。

j
jAndy

这是因为,在 ECMAscript 262 第 5 版之前,如果使用 constructor pattern 的人忘记使用 new 关键字,就会造成很大的混乱。如果您在 ES3 中调用构造函数时忘记使用 new,则 this 引用了全局对象(浏览器中的 window),您将使用变量破坏全局对象。

这是一种可怕的行为,因此 ECMA 的人们决定将 this 设置为 undefined

例子:

function myConstructor() {
    this.a = 'foo';
    this.b = 'bar';
}

myInstance     = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance  = myConstructor(); // oh my gosh, we just created a, and b on the window object

最后一行会在 ES5 strict 中抛出错误

"TypeError: this is undefined"

(这是一个更好的行为)


这是有道理的。你有支持声明的参考吗?
@RobW:我必须自己搜索,但我多次听到 Douglas Crockford 说,这就是做出这个决定的原因。
它在 Crockford 的 JavaScript: The Good Parts 中提到。它被详细描述。不过,与 ECMA 的决定无关。
这就是为什么严格模式将其默认为未定义的逻辑原因。另一个合乎逻辑的原因是效率,另一个合乎逻辑的原因是 this === window 令人困惑并将全局范围作为令牌泄漏到函数中
@jAndy:感谢您的回答。这是有道理的。我还在 javascriptweblog.wordpress.com/2011/05/03/… 上找到了对 this 更改的简洁解释:“最值得注意的是,如果调用或应用的第一个参数为 null 或未定义,则调用函数的 this 值不会转换为全局对象。”
P
Phrogz

有一种称为“装箱”的机制,它在进入被调用函数的上下文之前包装或更改 this 对象。在您的情况下,this 的值应该是 undefined,因为您没有将该函数作为对象的方法调用。如果是非严格模式,在这种情况下,这将被 window 对象替换。在 strict 模式下,它始终保持不变,这就是为什么这里是 undefined

您可以在
https://developer.mozilla.org/en/JavaScript/Strict_mode 找到更多信息


@samuel 那么我们如何在严格模式下将变量分配给窗口对象?
C
Community

根据 This Stack Overflow answer,您可以在匿名函数中使用 this,只需在其末尾调用 .call(this)

(function () {
    "use strict";

    this.foo = "bar";
}).call(this);

请注意,在这种情况下,this 将是 Window 对象,这可能不是我们所希望的
这个答案没有解释所提出的问题。