Странное поведение сравнения объектных литералов

Я искал, но не смог найти логику следования в JavaScript.

Когда я печатаю в консоли Chrome:

{} == null 

это возвращается

Uncaught SyntaxError: Неожиданный токен ==

Но

{} == {}

а также

{} == function(){} 

возвращает ложь

Зачем?

4 ответа

Решение

Я полагаю, вы понимаете, почему {} == null бросает SyntaxError, Короче говоря, это потому, что { в начале, начиная с блока, оператор не является литералом объекта. Вы можете проверить ответ здесь

Как и почему {} == {} это работает.

Если вы проверите код хрома, который оценивает выражения в консоли. Вы можете найти следующее ( код)

if (/^\s*\{/.test(text) && /\}\s*$/.test(text))
    text = '(' + text + ')';
executionContext.evaluate(text, "console", !!useCommandLineAPI, false, false, true, printResult);

Этот код переносит {} == {} код с круглыми скобками, делающий его допустимым выражением ({} == {}) сравнивая два пустых литерала объекта. Который оценивает false потому что объекты сравниваются по ссылке.

Узел repl имеет такое же поведение src

if (/^\s*\{/.test(code) && /\}\s*$/.test(code)) {
  // It's confusing for `{ a : 1 }` to be interpreted as a block
  // statement rather than an object literal.  So, we first try
  // to wrap it in parentheses, so that it will be interpreted as
  // an expression.
  code = `(${code.trim()})\n`;
  wrappedCmd = true;
}

Вы можете найти это в спецификации под Заявлением (статья 12)

12 - Заявление

Утверждение:
Блок. ВыраженияПрисваивания
EmptyStatement
ExpressionStatement
,
,
,

Первыми применимыми правилами являются либо блок, либо оператор выражения. Итак, нам нужно взглянуть на 12.4.

В 12.4 спецификации четко утверждают, что выражение выражения не может начинаться с {,

хотя я еще не нашел, что делает пример 2 выражением, может быть, это зависит от реализации

12.4 Выражение выражения

Синтаксис ExpressionStatement: [lookahead ∉ {{, function}] Expression;

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

Семантика Производство ExpressionStatement: [lookahead ∉ {{, function}] Expression; оценивается следующим образом:

Пусть exprRef будет результатом вычисления Expression. Возврат (обычный, GetValue(exprRef), пустой).

Я бы сказал, что это проблема разбора, а не логическая проблема как таковая.

В Chrome я получаю наблюдаемое поведение.

В IE я получаю синтаксические ошибки всякий раз, когда я ставлю {} (или, кажется, любой объектный литерал) на LHS ==,

В обоих браузерах выкладываю () вокруг выражения фиксированные вещи. Или сначала присвоить объект переменной

var x = {}
x == null

Я бы сказал, что это кажется мне ошибкой при разборе. Правда ли это в академическом смысле потребует копаться в спецификациях и грамматиках; практический ответ: есть достаточно простые обходные пути, поэтому лучше всего не делать этого.

Это потому, что JavaScript отстой. Причина, по которой он не работает, заключается в том, что JavaScript берет тип, который сравнивает первый объект.

Например

3+”1” = 4 

Но

“3”+1 = 31

Первый пример выполняет операцию как число, потому что первый объект является числом. Второй пример рассматривает строку как первый объект и рассматривает операцию как конкатенацию строки.

Для вашего примера {} является объектом, но нуль не может быть преобразован в объект

Это работает по-другому, потому что {} может быть представлен как нулевой объект.

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