严格模式下“this”关键字的默认绑定
我正在学习 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 ?
这实际上取决于您使用的浏览器以及它是如何 严格 地实现的。 如果您使用的浏览器完美实现了严格模式,则会看到错误。
来自
this
的文档
In strict mode, however, the value of this remains at whatever it was set to when entering the execution context, so, in the following case, this will default to undefined:
function f2() {
'use strict'; // see strict mode
return this;
}
f2() === undefined; // true
因此,在严格模式下,如果执行上下文未定义 this,则它保持未定义状态。
注意:
在第二个示例中,this 应该未定义,因为 f2 是直接调用的,而不是作为对象
的方法或属性调用的(例如 window.f2())。
某些浏览器在首次开始支持严格模式时未实现此功能。结果,他们错误地返回了窗口对象。
在我的浏览器中(最新的 Chrome,我可以看到错误)
function foo(){
"use strict";
alert(this.a);
}
var a = "Global A";
var obj = {
a : "Object's A",
foo : foo
}
setTimeout(obj.foo, 1000);
输出为“Global A”,因为
如果我们尝试在 setTimeout 函数之外执行 obj.foo(),则我们得到“Object's A”。这是因为在函数中使用“use strict”时,此关键字的上下文保留在调用它的任何内容上(此处它在 obj 上调用)。
但在上面的代码块中,obj.foo 在 setTimeout 内执行。 根据规则,setTimeout 在全局上下文中执行函数(但在箭头函数的情况下则不是)。 此处的 this 关键字将位于全局上下文中,因此我们得到“Global A”。
如果您在 chrome 中直接执行 foo() 函数(没有执行上下文),那么您将得到 Uncaught TypeError:无法读取未定义的属性“a”。 正如@Suresh Atta 所述 在严格模式下,如果执行上下文未定义 this,则它仍未定义。
如果您使用执行上下文(如 window.foo())执行 foo 函数,则“this”关键字将指向 window 对象,因此结果将是“Global A”。
this
的上下文取决于函数的调用方式。
函数
foo
设置在窗口对象上,其中也定义了
a
。
a
也是全局变量,因为它与
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);