Подтвердить что ты не робот

Почему {} == {} является ложным, но {} + {} == {} + {} истинно

Почему в node.js {} == {} эквивалентно false, но {} + {} == {} + {} эквивалентно true?

> {} == {}
false
> {} + {} == {} + {}
true
4b9b3361

Ответ 1

+ Вот оператор строки-конкатенации. Это:

{} == {}

означает "если я создаю один объект с помощью {}, а другой объект с {}, являются ли они одним и тем же объектом?"; и ответ "нет".

Это:

{} + {} == {} + {}

означает: "является примитивной строкой "[object Object][object Object]" той же самой, что и примитивная строка "[object Object][object Object]"?"; и ответ "да".


Отредактировано для добавления:. Количество комментаторов указывает, что в Chrome Web Console {} + {} выполняет числовое добавление, NaN + NaN, так что {} + {} == {} + {} фактически возвращает false (потому что это не верно, что NaN == NaN). Firefox Web Console дает тот же результат, что и Chrome, но если вы запустите его на странице, он даст тот же результат, что и node.js.

[Отредактировано: длинное объяснение того, как спецификация диктует, что {} + {} должна быть конкатенацией строк, а {} + {} == {} + {} - true; объяснение, правда, уже не очень интересно, учитывая ниже.]


Отредактировано для добавления: Благодаря комментарию jJ ', теперь я могу предложить лучшее объяснение несогласованности.

Причиной поведения веб-консоли является то, что веб-консоль не требует особого выражения; он с радостью примет что-то вроде if(true) { }. Итак, когда он видит {} + {}, он не интерпретирует это как выражение; начальный {} интерпретируется как голый блок, тогда + {} интерпретируется как выражение (создавая новый объект, преобразуя его в примитивное число, а именно NaN — и оценивая это число). Веб-консоль отображает результат последнего выражения (например, вход 3; 4 даст выход 4), который в этом случае равен NaN.

{} + {} == {} + {}, аналогично, интерпретируется как "пустой блок, за которым следует (+{}) == ({} + {})", т.е. "пустой блок, за которым следует NaN == '[object Object][object Object]'", то есть "пустой блок, за которым следует false".

Это можно исправить с помощью круглых скобок; ({} + {} == {} + {}), например, возвращает true.

(Это поведение, кстати, не совсем специфично для веб-консоли. eval следует тем же правилам, что eval('{} + {}') есть NaN и eval('({} + {})') is '[object Object][object Object]'.)