【问题标题】:Default binding of the "this" keyword in strict mode严格模式下“this”关键字的默认绑定
【发布时间】:2018-08-07 22:58:53
【问题描述】:

我正在学习 this 关键字是如何工作的,我读到当一个函数被简单地调用,没有任何上下文对象或 new 关键字时,this关键字只是指 global/window 对象。但如果函数使用严格模式,则this关键字设置为undefined。所以我写了这段代码来看看它是如何工作的:

function foo(){
    "use strict";
    alert(this.a);
}

var a = "Global A";

var obj = {
    a : "Object's A",
    foo : foo
}

setTimeout(obj.foo, 1000);

我以为我会收到一个错误提示 Uncaught TypeError: Cannot read property 'a' of undefined。但令我惊讶的是,输出是 Global A。函数 foo() 是在严格模式下编写的。但是,this 关键字仍然指的是 global 对象。为什么输出是 Global A 而不是 TypeError

【问题讨论】:

  • 可能是函数声明不是严格模式?请注意,您在这里松散了范围:setTimeout(obj.foo, 1000)
  • @JonasW。我认为如果函数体处于严格模式,则足以使 this 引用 undefined。但我不是 100% 确定:+

标签: javascript this


【解决方案1】:

这实际上取决于您使用的浏览器以及它的实现方式严格。如果您使用的是完美实现严格模式的浏览器,您会看到错误。

来自this的文档

然而,在严格模式下, this 的值保持在进入执行上下文时设置的任何值,因此,在以下情况下, this 将默认为 undefined:

function f2() {
  'use strict'; // see strict mode
  return this;
}

f2() === undefined; // true

因此,在严格模式下,如果执行上下文没有定义它,它仍然是未定义的。

注意: 在第二个示例中,这应该是未定义的,因为 f2 是直接调用的,而不是作为对象的方法或属性 (e.g. window.f2()). 此功能不是t 在某些浏览器刚开始支持严格模式时已实现。结果,他们错误地返回了 window 对象。

在我的浏览器中(最新的 Chrome,我可以看到错误)

https://jsfiddle.net/1mp0hq03/1/

【讨论】:

  • 感谢您的回答!!但是当我在 Chrome 的控制台中执行代码(我在问题中提到的那个)时,输出是 Global A。但是,在 JSFiddle 中运行相同的代码会产生 TypeError。诡异的! -_-
【解决方案2】:

this 的上下文取决于函数的调用方式。

函数foo 设置在窗口对象上,其中还定义了aa 也是全局变量,因为它与var 一起使用

function foo() {
  "use strict";
  console.log(window.foo) // will log the foo function
  alert(this.a);
}

var a = "Global A";

var obj = {
  a: "Object's A",
  foo: foo
}

setTimeout(obj.foo, 1000);

【讨论】:

    【解决方案3】:

    参考MDN

    由 setTimeout() 执行的代码是从与调用 setTimeout 的函数不同的执行上下文中调用的。为被调用函数设置 this 关键字的通常规则适用,如果您没有在调用或绑定中设置 this,它将默认为窗口(或全局)对象。它不会与调用 setTimeout 的函数的 this 值相同。

    【讨论】:

      猜你喜欢
      • 2017-01-07
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 2019-02-01
      • 1970-01-01
      • 2020-02-05
      • 2020-06-13
      相关资源
      最近更新 更多