Почему в node.js {} == {}
эквивалентно false
, но {} + {} == {} + {}
эквивалентно true
?
> {} == {}
false
> {} + {} == {} + {}
true
Почему в node.js {} == {}
эквивалентно false
, но {} + {} == {} + {}
эквивалентно true
?
> {} == {}
false
> {} + {} == {} + {}
true
+
Вот оператор строки-конкатенации. Это:
{} == {}
означает "если я создаю один объект с помощью {}
, а другой объект с {}
, являются ли они одним и тем же объектом?"; и ответ "нет".
Это:
{} + {} == {} + {}
означает: "является примитивной строкой "[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]'
.)