#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:
Я думаю, вы можете сначала присвоить оба объекта переменным и сравнить эти две переменные вместо того, чтобы создавать их в операторе. Ваша проблема заключается в том, что вы присваиваете в инструкции. Добавляя (), вы обертываете это назначение как оператор, и оно работает нормально.