【问题标题】:Why is "this" in an anonymous function undefined when using strict?为什么在使用严格时未定义匿名函数中的“this”?
【发布时间】:2017-10-31 02:19:17
【问题描述】:

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

例子:

(function () {
    "use strict";

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

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

【问题讨论】:

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

标签: javascript anonymous-function use-strict


【解决方案1】:

这是因为,在 ECMAscript 262 第 5 版之前,如果使用 constructor pattern 的人忘记使用 new 关键字,就会造成很大的混乱。如果你在 ES3 中调用构造函数时忘记使用newthis 引用了全局对象(浏览器中的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 值将不会是转换为全局对象。”
【解决方案2】:

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

您可以在
https://developer.mozilla.org/en/JavaScript/Strict_mode

找到更多信息

【讨论】:

  • @samuel 那么我们如何在严格模式下将变量分配给窗口对象??
【解决方案3】:

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

(function () {
    "use strict";

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

【讨论】:

  • 请注意,在这种情况下,this 将是 Window 对象,这可能不是我们所希望的
  • 这个答案没有解释所提出的问题。
猜你喜欢
  • 2015-07-10
  • 2017-02-20
  • 2018-08-17
  • 1970-01-01
  • 2015-05-12
  • 2016-11-30
  • 1970-01-01
  • 2012-02-01
相关资源
最近更新 更多