在 Node.js 和浏览器中对 'this' 的不同处理

Different handling of 'this' in Node.js and Browser

我在本地安装了 Node.js v8.10.0。我写了一个简单的脚本来玩 'this':

var x = 1;

var fn = function (a) {
     var x = a;

     console.log(`local x = ${x}`);
     console.log(`global x = ${this.x}`);
}

fn(10);

当我通过 Node.js 执行脚本时,我得到以下结果:

local x = 10

global x = undefined

当我在 Chrome 中执行脚本时,我得到以下结果:

local x = 10

global x = 1

你能给我解释一下吗,为什么 Node.js 在全局范围内看不到 x?

Could you please explain to me, why Node.js doesn't see x in global scope?

如果你在 Node 控制台中 运行 它确实如此。如果您 运行 它作为一个文件,x 是在 文件的范围 ,而不是全局范围。

顺便说一句,在 Node 中,您可以使用 global 来显式查看全局范围,就像您在浏览器中使用 window 一样。因此,

console.log(global == this)

将根据您 运行 它是在文件中还是在控制台中给您两个不同的答案。

另外,尝试迁移到 letconst。这更加令人困惑,因为 var 在全局范围和其他地方的行为不同。在控制台和浏览器中,您的外部 var x 在全局范围内,因此它定义了一个全局变量(window.xglobal.x)。在 Node 文件中,var x 不在全局范围内,因此它执行不在全局范围内时通常执行的操作:定义一个 local 变量 x (不是 this.x,不是 global.x,只是 x)。因此,您有两个局部变量,内部变量覆盖外部变量,这使得外部变量不可访问。同时,this.x 从未被定义。

在 chrome 中 thisWindow 的对象,就好像你做 this.constructor.name 你得到 Window 作为构造函数名称所以在访问 this.x 它将查找全局变量 x 并且不引用函数范围。

var x = 1;

var fn = function (a) {
     var x = a;

     console.log(`local x = ${x}`);
     console.log('Constructor ', this.constructor.name);
     console.log(`global x = ${this.x}`);
}

fn(10);

然而,在 NodeJS 中,this 将始终引用函数原型(而不是全局范围)。因此,您没有任何值 x 与函数的 prototype 关联,因此它给您 undefined.