【问题标题】:'this' different between REPL and scriptREPL和脚本之间的'this'不同
【发布时间】:2014-01-01 01:46:17
【问题描述】:

阅读mozilla docs后发现:

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

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

> this === global
true

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

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

这是有原因的吗?还是bug?

【问题讨论】:

    标签: javascript node.js this global


    【解决方案1】:

    节点的REPL 是全局的。文件中的代码位于“模块”中,实际上只是一个函数。

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

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

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

    【讨论】:

    • 确实,console.log(this === exports); 记录了true。有趣的。我认为“Nodes REPL 是全局的”并不能真正回答为什么 REPL 会调用您使用 this = global 输入的代码,但这很好地解释了 this 在模块中的含义。这是在文档中的某个地方吗?
    • 好吧,确实有道理。
    • @T.J.Crowder:我不知道它是否被记录在案。我通过阅读源代码了解了它的工作原理。这也是 Node 能够使require() 幂等的方式。 ctx 对象被缓存并在后续调用中返回。
    • ...“REPL 是全局的”,我的意思是提供的代码是在全局范围内执行的,所以它的 this 是全局对象,无论我们是不是在严格模式下,如 MDN 参考所述。
    • @cookiemonster: :-) 多年后,Node 的文档仍有很多不足之处。啊,好吧...也许有一天我会足够了解 Node 以帮助改善这种情况,尽管我总是让我很讨厌回去记录其他人的东西。
    【解决方案2】:

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

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

    【讨论】:

    • 确实如此,但它并没有解释this,因为脚本中的this 不是指模块的范围(即该执行的执行上下文的变量绑定对象模块)。例如。 var x = 42; console.log(this.x); 在脚本中记录 undefined。我没有立即找到任何说明 this 在模块中的内容(它记录为空对象),或者任何说明 REPL 使用 this = global 评估您的代码的内容。
    • @T.J.Crowder 是的,我现在是一个新手节点,所以我不确定节点在做什么。我从来没有想过尝试通过this访问范围,但这当然是存在Stackoverflow问题的原因:)
    • @T.J.Crowder 然而,从运行node 得到的普通REPL 来看,this 确实看起来是全局的,如果你尝试var 测试它也可以:@ 987654331@ 打印正确的值。
    • 是的,REPL 肯定是用this = global 执行代码。
    猜你喜欢
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 2013-10-23
    • 2021-09-12
    • 2016-11-09
    • 1970-01-01
    相关资源
    最近更新 更多