In the console of both FF and Chrome, {} is considered undefined until explicitly evaluated:
{}; // undefined
({}); // ▶ Object
Actually, it’s a bit less defined than undefined — it’s apparently bad syntax:
{} === undefined; // SyntaxError: Unexpected token ===
{}.constructor; // SyntaxError: Unexpected token .
But not if it’s on the other side, in which case it’s fine:
"[object Object]" == {}.toString(); // true
Or if it’s not the first expression:
undefined + undefined; // NaN
{} + undefined; // NaN
undefined + {}; // "undefined[object Object]"
What gives?
Okay, here is my answer. There is nothing new here. I am just linking to (a pretty copy of) the ECMAScript specification for the grammar and showing a few productions to show “why” it parses the way it does. In any case, the behavior is well-defined according to the JavaScript/ECMAScript grammar rules:
{}is parsed differently depending upon the “context” it is in.The JavaScript REPLs (“consoles”) start to parse the code in the
Statementgrammar production or “statement context”. (This is actually a lie, it starts at theProgramorSourceElementsproduction, but that adds additional constructs to dig through.) Here is a rough grammar breakdown with simplifications and omissions; see the link above for more:Thus (when in “statement context”):
And:
This also explains why
undefined === {}parses asEXPR === EXPR -> EXPR -> STMTand results in false when evaluated. The{}in this case is in an “expression context”.In the case of
{} === undefinedit is parsed as{}; === undefined, orBLOCK; BOGUS -> STMT; BOGUS, which is a Syntax Error. However, with the addition of parenthesis this changes:({} === undefined)is parsed as(EXPR === EXPR) -> (EXPR) -> EXPR -> STMT.In the case of
{} + "hi"it is parsed as{}; + "hi", orBLOCK; + EXPR -> STMT; EXPR -> STMT; STMT, which is valid syntax even though it is silly (+is unary in this case). Likewise, just as above,"hi" + {}puts the{}into an “expression context” and it is parsed asEXPR + EXPR -> EXPR -> STMT.The JavaScript console is just showing the result of the last Statement, which is “undefined” (well, “nothing” really, but that doesn’t exist) for an empty
{}block. (This might vary between browsers/environments as to what is returned in this case, e.g. last ExpressionStatement only?)Happy coding.