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


85

在严格模式下使用javascript时,为什么在匿名函数中未定义函数?我知道为什么这样做有意义,但是我找不到任何具体答案。

例:

(function () {
    "use strict";

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

在小提琴中测试:http : //jsfiddle.net/Pyr5g/1/ 检查记录器(firebug)。


4
请注意,这与匿名函数无关,而与调用方法无关。请参阅此修改过的小提琴(在控制台日志中查看)。
Phrogz 2012年

@Phrogz:这可能是一些混乱的来源。感谢您指出了这一点。
T. Junghans,2012年

Answers:


101

这是因为,在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"

(这是一个更好的行为)


4
这很有道理。您是否有备份该声明的参考?
罗伯W

1
@RobW:我必须进行自我搜索,但是我多次听到道格拉斯·克罗克福德(Douglas Crockford)的讲话,这就是做出这一决定的原因。
jAndy 2012年

1
它在Crockford的JavaScript:The Good Parts中提到。详细说明。不过,这与ECMA的决定无关。
madr 2012年

1
这是为什么严格模式将其默认设置为undefined的逻辑原因。另一个逻辑原因是效率,另一个逻辑原因是this === window令人困惑,并且将全局范围作为令牌泄漏给函数
Raynos 2012年

2
@jAndy:谢谢你的回答。这很有道理。我还在javascriptweblog.wordpress.com/2011/05/03/…上找到了对此更改的简要说明:“最值得注意的是,如果要调用或应用的第一个参数为null或未定义,则所调用函数的this值将不会转换为全局对象。”
T. Junghans,2012年

15

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

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


@samuel那么我们如何才能在严格模式下将变量分配给窗口对象?
空指针

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.