我正在研究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章没有对该问题提供任何解释。
答案 0 :(得分:3)
用this
引用全局变量是一个不好的做法,因为尚不清楚在哪个范围内评估脚本。访问全局变量的唯一可靠方法是使用间接评估(直到globalThis
可用,当前可以是polyfilled)。
对于节点:
(0, eval)('this') === global
对于浏览器(可以使用CSP禁用):
(0, eval)('this') === window
据我了解,在foo()中,这是指全局对象,因为直接调用了函数。
这是实际问题。节点脚本在模块范围内评估,var count
在module wrapper范围内创建局部变量,而this
引用module.exports
。