Различия между Node.js и Node.js REPL

Я читаю серию книг «Вы не знаете JS» и попытался запустить фрагмент:

function foo() {
  console.info( 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.info(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.info(this);

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

{
   ...
   x: 42
}

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

Я пришел к такому же выводу, что и ваше изменение, вы можете опубликовать его как ответ на свой вопрос.

DrakaSAN 16.04.2018 10:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
241
1

Ответы 1

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

Тогда как в REPL это действительно глобально.

Извините, если я настаиваю, но я бы попытался хорошо понять: это та же самая причина, по которой при загрузке Node.js REPL с помощью Object.prototype; и Array.prototype он отвечает с помощью { } и [ ], в то время как с тем же вводом движок браузера (например, Chrome v8) отвечает с {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …} и [constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]? Спасибо за ваше время.

Daniele Paolini 18.04.2018 09:35

Совсем не та же причина (т.е. сфера действия). Это больше связано с тем, как движок решает их показать. .prototype - интересный объект, о котором стоит прочитать отдельно. Но в основном он имеет некоторые общие свойства, такие как constructor, hasOwnProperty и т. д. Chrome, показывающий {constructor ...} для Object.prototype, и [constructor ...] для Array.prototype, - лишь его стилистический выбор. Firefox отображает это иначе. Node вообще не отображает эти внутренние свойства, но вы все равно сможете получить к ним доступ, если укажете их по имени, то есть Object.prototype.constructor.

laggingreflex 18.04.2018 13:32

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