首页 > 解决方案 > nodejs vs Chrome中的不同全局对象

问题描述

我正在浏览你不知道的 JS 系列中提供的示例 - this 和 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);

铬(73.0.3683.75)10003

NodeJS(v6.10.2) 9999

据我了解,在 foo() 中this是指直接调用函数的全局对象。因此,this.count指的是全局对象上的计数变量。因此,当“this.count++”执行时,它实际上会在全局对象(Chrome 的情况下为窗口)上创建一个新的计数变量并增加相同的值。

我感到困惑的是,NodeJs 的行为是不同的。如果我稍微修改如下代码以检查节点中全局变量的计数值,我会看到它的值为 NaN。NodeJs的修改代码

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 和 NodeJs 中有两种不同的行为。

此外,Kyle 说,以下问题的答案将在第 2 章中找到,“它是如何全局化的,为什么它以 NaN 而不是一些适当的计数值结束?” (见第 2 章)”但是本书的第 2 章没有对这​​个问题提供任何解释。

标签: javascriptnode.js

解决方案


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

对于节点:

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

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

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

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

这是实际的问题。节点脚本在模块范围内评估,在模块包装器var count范围内创建局部变量,同时引用.thismodule.exports


推荐阅读