Why in node.js is {} == {} equivalent to false, but is {} + {} == {} + {} equivalent to true?
> {} == {}
false
> {} + {} == {} + {}
true
Why in node.js is {} == {} equivalent to false, but is {} + {} == {} + {} equivalent to true?
> {} == {}
false
> {} + {} == {} + {}
true
+ here is the string-concatenation operator. This:
{} == {}
means "if I create one object with {}, and another object with {}, are they the same object?"; and the answer is "no".
This:
{} + {} == {} + {}
means "is the primitive string "[object Object][object Object]" the same as the primitive string "[object Object][object Object]"?"; and the answer is "yes".
Edited to add: A number of commenters point out that in Chrome's Web Console, {} + {} performs numeric addition, NaN + NaN, such that {} + {} == {} + {} actually returns false (because it's not true that NaN == NaN). Firefox's Web Console gives the same result as Chrome's, but if you run this inside a page, it gives the same result as node.js.
[Redacted: long explanation of how the spec dictates that {} + {} should be string concatenation and {} + {} == {} + {} should be true; the explanation, while correct, is no longer terribly interesting, given the below.]
Edited to add: Thanks to a comment by jJ', I can now offer a better explanation of the inconsistency.
The reason for the Web Console's behavior is that the Web Console does not specifically require an expression; it will happily accept something like if(true) { }. So, when it sees {} + {}, it doesn't interpret that as an expression; the initial {} is interpreted as a naked block, then the + {} is interpreted as an expression (creating a new object, converting it to a primitive number — namely NaN — and evaluating to that number). The Web Console displays the result of the last expression (e.g., the input 3; 4 will give the output 4), which in this case is NaN.
{} + {} == {} + {}, similarly, is interpreted as "empty block, followed by (+{}) == ({} + {})", i.e., "empty block, followed by NaN == '[object Object][object Object]'", i.e. "empty block, followed by false".
This can be fixed by using parentheses; ({} + {} == {} + {}), for example, returns true.
(This behavior, by the way, is not completely specific to the Web Console. eval follows the same rules, such that eval('{} + {}') is NaN and eval('({} + {})') is'[object Object][object Object]'.)