在浏览器中,在全局范围内运行,this 在您的示例中始终为 window
var obj1;
var obj2;
function x() {
obj1 = this; // window
}
function y() {
obj2 = this; // window
}
x();
y();
console.log(obj1 === obj2); // window === window = true
console.log(obj1 === this); // window === window = true
这不是它在 Node.js 中的工作方式。在 Node.js 中,所有模块(脚本文件)都在它们自己的 closure 中执行,而浏览器则直接在全局范围内执行所有脚本文件。
换句话说,在 Node 中运行的任何文件中,this 将只是一个空对象,因为 Node 将代码包装在一个立即调用的匿名函数中,并且您可以访问其中的全局范围改为GLOBAL 的上下文。
Globals documentation中也提到了这一点:
其中一些对象实际上不在全局范围内,而是在模块范围内 - 这将被注明。
但是,在 Node.js 中调用没有特定上下文的函数时,它通常会默认为 全局对象 - 与前面提到的 GLOBAL 相同,因为它是执行上下文。
所以在函数之外,this 是一个空对象,因为代码被 Node 包装在一个函数中,以便为每个模块(脚本文件)创建它自己的执行上下文,而在函数内部,因为它们是 在没有指定执行上下文的情况下调用,this 是 Node GLOBAL 对象
在 Node.js 中你会得到
var obj1;
var obj2;
function x() {
obj1 = this; // GLOBAL
}
function y() {
obj2 = this; // GLOBAL
}
x();
y();
console.log(obj1 === obj2); // GLOBAL === GLOBAL = true
console.log(obj1 === this); // GLOBAL === {} = false
最后一个this确实是一个空对象,如上所述
为了完整起见,值得注意的是,在严格模式下,您会在浏览器 (true, false) 中获得与在 Node 中相同的结果,但这是因为变量与它们在 Node 中的结果正好相反
"use strict"
var obj1;
var obj2;
function x() {
obj1 = this; // undefined
}
function y() {
obj2 = this; // undefined
}
x();
y();
console.log(obj1 === obj2); // undefined === undefined = true
console.log(obj1 === this); // undefined === window = false
这是因为作为 this 传递给严格模式下的函数的值不会被强制成为对象(也称为“装箱”)。
对于非严格模式下的普通函数,this 始终是一个对象,如果 调用 带有 undefined 或 null 这个值,即没有特定的值,它始终是全局对象执行上下文。
automatic boxing 不仅是性能成本,而且在浏览器中公开全局对象也是一种安全隐患,因为全局对象提供了对 JavaScript 环境必须限制的“安全”功能的访问。
因此对于严格模式函数,指定的this 不会被装箱到对象中,如果未指定,this 将是函数内部的undefined,如上所示,但this 仍将是窗口在全局范围内。
同样的事情发生在 Node.js 的严格模式下,其中函数内部的 this 不再是 GLOBAL 而是 undefined,而函数外部的 this 仍然是同一个空对象,并且最终结果仍然是true, false,但在 Node.js 的严格模式下this 的值也会有所不同。