Node.js和Chrome中的不同全局对象

时间:2019-03-16 13:10:31

标签: javascript node.js

我正在研究You Don't know JS series - this and Object prototype中提供的示例。我稍稍更改了代码,然后在Chrome和Node Js上进行了测试。输出有所不同。所以这是代码:

function foo(num) {
// keep track of how many times `foo` is called
    this.count++;
}

var count = 9999;
var i;
for (i=0; i<10; i++) {
    if (i > 5) {
        foo( i );
    }
}
console.log(count);

Chrome(73.0.3683.75) 10003

NodeJS(v6.10.2) 9999

据我了解,在foo()this中是指直接调用函数的全局对象。因此,this.count引用了全局对象上的count变量。因此,当执行“ this.count ++”时,实际上会导致在全局对象上创建一个新的count变量(在Chrome中为窗口),并将其递增。

让我感到困惑的是,在NodeJ的情况下,行为是不同的。如果我稍微修改以下代码以检查节点中全局变量的count值,就会看到它的值为NaN。 修改的NodeJ代码

function foo(num) {
    this.count++;
}

var count = 9999;
var i;
for (i=0; i<10; i++) {
    if (i > 5) {
        foo( i );
    }
}
console.log(count);
console.log(global.count);

输出

9999
NaN

所以,我想了解一下为什么我们在Chrome和NodeJ中有两种不同的行为。

此外,凯尔说,以下问题的答案将在第2章中找到 “它是如何全局的,为什么它以NaN而不是某个适当的计数值结尾?” (请参阅第2章)” 但是本书的第2章没有对该问题提供任何解释。

1 个答案:

答案 0 :(得分:3)

this引用全局变量是一个不好的做法,因为尚不清楚在哪个范围内评估脚本。访问全局变量的唯一可靠方法是使用间接评估(直到globalThis可用,当前可以是polyfilled)。

对于节点:

(0, eval)('this') === global

对于浏览器(可以使用CSP禁用):

(0, eval)('this') === window
  

据我了解,在foo()中,这是指全局对象,因为直接调用了函数。

这是实际问题。节点脚本在模块范围内评估,var countmodule wrapper范围内创建局部变量,而this引用module.exports