Почему существуют различия между REPL узла и скриптом узла, работающим при оценке этих выражений

Почему существует разница между тем, как Node REPL и механизм Node, работающий со сценарием, интерпретируют следующее выражение: {...a}?

Я запускаю узел v8.3.0 (обнаруженный при запуске node -v) и обнаружил странную разницу между интерпретацией командной строки и интерпретацией скрипта операторов распространения.

Рассмотрим следующее:

$ node -v
v8.3.0
$ node

(Получение версии узла и последующий запуск интерпретатора узла)

> const a = {foo: 'bar'};
undefined
> {...a};
{ foo: 'bar' }

(Создание литерала объекта и сохранение его в const a. Затем создание другого литерала объекта и заполнение spread operator на a.

Все идет нормально. Но если вы создадите file.js:

const a = { foo: 'bar' };
{...a};

и запустите > node file.js, результат будет SyntaxError: Unexpected token ....

Я мог бы ответить на свой вопрос, но моя текущая операционная теория заключается в том, что Node обычно интерпретирует { и } как блок исполняемого кода, тогда как интерпретатор Node live ищет в основном автономные выражения. (Этот ответ подразумевает, что все заключено в скобки, в чем я сомневаюсь, потому что возможны многострочные блоки кода, но он, вероятно, на правильном пути).

Но если это так, то почему { foo: 'bar' } (автономный) оценивается без ошибок как в REPL, так и в сценарии Node?

Следующее выполняется без ошибок как в REPL, так и в сценарии Node:

[1, 2, 3]
[...a]
{foo: 'bar'}

Но это не работает в узле:

{...b}

Какую разницу вносит оператор спреда?


Изменить: согласно Pointy, {foo: 'bar'} действительно оценивает автономно, но { foo: 'bar', sna: 'fu' } нет. Node интерпретирует код между фигурными скобками как блок кода, и foo: 'bar' является допустимым выражением Javascript, а ...a и foo: 'bar', sna: 'fu' — нет.


person Isaiah Taylor    schedule 04.01.2018    source источник
comment
Когда вы нажимаете Enter в REPL, я предполагаю, что он ожидает выражение и, вероятно, делает что-то похожее на заключение оператора в круглые скобки. редактировать: да, по словам Акселя Раушмайера, это происходит   -  person Denys Séguret    schedule 04.01.2018


Ответы (1)


Все дело в том, как анализируется оператор. Оператор (не выражение), начинающийся с {, является блоком операторов. Когда в выражении появляется {, оно вводит литерал объекта.

Заявление:

{ foo: 'bar' }

синтаксически правильно, но семантически отличается, когда интерпретируется как утверждение и когда интерпретируется как выражение. В первом случае это оператор блока:

{
   foo: 'bar'
}

который представляет собой блок, содержащий один оператор, выражение с меткой 'bar'. Это не объектный литерал.

Выражение {...a} терпит неудачу, когда { вводит блок инструкций, потому что ...a само по себе не может быть проанализировано как инструкция.

person Pointy    schedule 04.01.2018
comment
developer.mozilla.org/en-US/docs/ Web/JavaScript/Reference/ интересно... подтвердил, что {foo: 'bar', sna: 'fu'} не оценивает. - person Isaiah Taylor; 04.01.2018