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

IT技术 javascript anonymous-function use-strict
2021-02-08 02:06:04

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

例子:

(function () {
    "use strict";

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

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

3个回答

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

这是可怕的行为,所以 ECMA 的人决定,只是设置thisundefined.

例子:

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 严格中抛出错误

"TypeError: this is undefined"

(这是一个更好的行为)

这就是为什么严格模式默认 this 为 undefined 的逻辑原因。另一个合乎逻辑的原因是效率,另一个合乎逻辑的原因this === window是混淆并将全局范围作为令牌泄漏到函数中
2021-03-14 02:06:04
它在 JavaScript: The Good Parts by Crockford 中提到。它被详细描述。不过,这与 ECMA 的决定无关。
2021-03-23 02:06:04
@jAndy:感谢您的回答。这是有道理的。我还在javascriptweblog.wordpress.com/2011/05/03 /...找到了对此变化的简洁解释:“最值得注意的是,如果调用或应用的第一个参数为空或未定义,则调用函数的 this 值不会转换为全局对象。”
2021-03-31 02:06:04
@RobW:我必须自己搜索,但我多次听到道格拉斯·克罗克福德 (Douglas Crockford) 说,这就是做出该决定的原因。
2021-04-01 02:06:04
这是有道理的。您有参考资料来支持该声明吗?
2021-04-09 02:06:04

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

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

@samuel 那么我们如何在严格模式下为 window 对象分配一个变量??
2021-03-16 02:06:04

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

(function () {
    "use strict";

    this.foo = "bar";
}).call(this);
这个答案并没有解释所提出的问题。
2021-03-22 02:06:04
请注意,在这种情况下this将是Window对象,这可能不是我们想要的
2021-04-08 02:06:04