Различия между Node.js и Node.js 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"

(Вы можете найти это во 2-й главе 3-й книги: "это". Все теперь имеет смысл)

Если я сохраню это в 'foo.js' и запусту его с узлом 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. Это имеет больше смысла для меня, потому что таким образом я устанавливаю свойство для глобального объекта, в то время как "оригинальным" способом я просто объявляю переменную.

Кто-нибудь может объяснить мне это поведение? Спасибо вам всем.

РЕДАКТИРОВАТЬ: Я думаю, что я близок к решению, я заметил, что если я сделаю сценарий foo.js, который содержит только:

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

я получил {}, так x не привязан к глобальному объекту. Хотя, если я запускаю Node.js REPL и набираю тот же код, я получаю большой объект с x прикреплен к нему:

{
   ...
   x: 42
}

Поэтому я думаю, что разница зависит от того, "кто является глобальным объектом?" в REPL и в Node.js.

1 ответ

Когда вы запускаете файл в Node.js, ваш var a на самом деле не в глобальной области видимости, а в области действия функции - в области действия модуля (подробнее об этом здесь). В основном все содержимое файла запускается как будто внутри функции. Так var a на самом деле в этой области действия функции.

В то время как в REPL это действительно в глобальном масштабе.

Другие вопросы по тегам