REPL 和脚本之间的“这个”不同

IT技术 javascript node.js this global
2021-01-24 16:15:46

阅读完mozilla 文档后,我发现了这一点:

在全局执行上下文中(在任何函数之外), this 指的是全局对象,无论是否处于严格模式。

在玩了一会儿范围之后,我发现在 node.js REPL 中......

> this === global
true

但是当我用同一行创建脚本时......

$ cat > script.js
console.log(this === global)
$ node script.js
false

是否有一个原因?或者这是一个错误?

2个回答

节点REPL是全球性的。文件中的代码位于“module”中,它实际上只是一个函数。

你的代码文件变成了这样一个非常简单的例子:

var ctx = {};
(function(exports) {
    // your code
    console.log(this === global);
}).call(ctx, ctx);

请注意,它是使用 执行的.call(),并且该this值被设置为一个预定义的对象。

@TJCrowder:我不知道它是否被记录在案。我通过阅读源代码了解了它的工作原理。这也是 Node 能够实现require()幂等的方式。ctx对象被缓存并在后续调用中返回。
2021-03-15 16:15:46
...“REPL是全局的”,我的意思是提供的代码在全局范围内执行,因此this无论我们是否处于严格模式,都是全局对象,如 MDN 参考所述。
2021-03-23 16:15:46
@cookiemonster: :-) 多年后,Node 的文档仍然有很多不足之处。啊,好吧...也许有一天我会充分了解 Node 以帮助改善这种情况,尽管我总是很讨厌回去记录其他人的东西。
2021-03-29 16:15:46
好的,这肯定是有道理的。
2021-04-04 16:15:46
事实上,console.log(this === exports);日志true有趣的。我不认为“节点 REPL 是全球性的”真正回答了为什么 REPL 调用您输入的代码的原因this = global,但这很好地解释了thismodule中的内容。这是在文档中的某个地方吗?
2021-04-11 16:15:46

当您使用 node 从文件运行脚本时,它会隐式地将其设置为具有自己作用域的module。

当您在没有文件的情况下直接运行它时,您将被放入 REPL 但不在任何module范围内。

这是真的,但它没有解释this,因为this在脚本中没有指代module的范围(即,module执行的执行上下文的变量绑定对象)。例如,var x = 42; console.log(this.x);登录undefined脚本。我没有立即找到任何说明thismodule中的内容(它记录为空对象),或者任何说明 REPL 使用this = global.
2021-03-16 16:15:46
@TJCrowder 但是,从您从运行中获得的普通 REPL 中node,它确实看起来确实this是全局的,如果您尝试该var测试,它也确实如此:var foo = "hello world"; global.foo;打印正确的值。
2021-03-17 16:15:46
@TJCrowder 是的,此时我是一个新手 Node,所以我不确定 Node 在做什么。我从来没有想过尝试通过 访问范围this,但这当然就是 Stackoverflow 问题存在的原因:)
2021-03-30 16:15:46
是的,REPL 肯定是用this = global.
2021-04-04 16:15:46