Почему в Javascript {a : 1 } == {a : 1} выдает ошибку, а ({a : 1}) == {a : 1} будет работать?

#javascript

#javascript

Вопрос:

Это делается в Firebug:

 >>> {a : 1} == {a : 1}
SyntaxError: syntax error
[Break On This Error] {a : 1} == {a : 1} 

>>> ({a : 1}) == {a : 1}
false
  

Так и должно быть ({a : 1}) == {a : 1} , почему это так?

Ответ №1:

Потому {a : 1} что это объявление, и ему не разрешено следовать, == однако

({ a : 1 }) является выражением, за которым может следовать ==

Это в основном правила, определенные в грамматике.

Однако обратите внимание, что ({ a: 1} == { a: 1}) это действительно так. Таким образом, выражение эквивалентности является действительным.

Это означает, что {a : 1} == { a : 1 } это просто недопустимое утверждение.

12.4 спецификации ES5.1 гласит

ОБРАТИТЕ ВНИМАНИЕ, что выражение ExpressionStatement не может начинаться с открывающей фигурной скобки, потому что это может сделать его неоднозначным с блоком. Кроме того, выражение ExpressionStatement не может начинаться с ключевого слова function , потому что это может сделать его неоднозначным с FunctionDeclaration .

В качестве примечания вы обнаружите, что

({a : 1}) != {a : 1} потому что это два новых объекта

Комментарии:

1. Вы уверены? Я ожидаю !== сбоя, но не !=

Ответ №2:

Начальный символ «{» интерпретируется синтаксическим анализатором как запуск блока операторов, а не как запуск выражения. Это двусмысленность в языке, и именно так она решается (в соответствии со спецификацией).

Это похоже на двусмысленность вокруг function ключевого слова. Когда оператор начинается с function , это оператор объявления функции, хотя синтаксически он может быть задуман как начало выражения. Синтаксические анализаторы просто должны разрешать такие неоднозначности в соответствии с некоторыми правилами.

Комментарии:

1. 12.4 — это ссылка на то, что a { должен быть блоком и не может быть выражением

2. Ах, спасибо! Мне нужно на самом деле сохранить копию спецификации на днях вместо того, чтобы возвращаться на сайт ecma и загружать его все время — это так медленно 🙂

Ответ №3:

Я думаю, вы можете сначала присвоить оба объекта переменным и сравнить эти две переменные вместо того, чтобы создавать их в операторе. Ваша проблема заключается в том, что вы присваиваете в инструкции. Добавляя (), вы обертываете это назначение как оператор, и оно работает нормально.