Node.js和Node.js REPL之间的差异

时间:2018-04-16 07:38:19

标签: javascript node.js javascript-engine node-repl

我正在阅读"你不了解JS"书系列,我试图运行该片段:

function foo() {
  console.log( this.a );
}

function doFoo(fn) {
  // `fn` is just another reference to `foo`

  fn(); // <-- call-site!
}

var obj = {
  a: 2,
  foo: foo
};

var a = "oops, global"; // `a` also property on global object

doFoo( obj.foo ); // "oops, global"

(你可以在3d书的第二章找到它:&#39;这个&#39;现在都有意义

如果我把它保存到&#39; foo.js&#39;并使用 node foo.js (v 8.11.1)运行它,然后我得到undefined。如果我启动节点REPL并输入相同的代码,我得到:

> function foo() { console.log(this.a); }
undefined
> function doFoo(fn) { fn(); }
undefined
> var obj = { a:2, foo:foo };
undefined
> var a = "oops, global";
undefined
> doFoo(obj.foo);
oops, global
undefined

正如预期的那本书。 Firefox开发者控制台上的结果相同。

如果我删除声明并只保留赋值a = "oops, global",那么它在REPL和Node.js上都按预期运行。这对我来说更有意义,因为通过这种方式,我在全局对象上设置属性,而在&#34;原始&#34;方式我只是声明一个变量。

任何人都可以向我解释这种行为吗?谢谢大家。

编辑:我认为我接近解决方案,我注意到如果我创建一个仅包含的脚本 foo.js

var x = 42;
console.log(this);

我得到{},因此x未附加到全局对象。如果我启动Node.js REPL并输入相同的代码,我会得到一个附加x的大对象:

{
   ...
   x: 42
}

所以我认为这取决于&#34;谁是全球对象?&#34;在REPL和Node.js中。

1 个答案:

答案 0 :(得分:1)

在Node.js中运行文件时,var a实际上不在全局范围内,而是函数范围 - 模块函数范围(更多关于此here)。基本上,文件的所有内容都像在函数内部一样运行。所以var a实际上就在那个函数范围内。

而在REPL,它确实在全球范围内。