I have searched but could not find logic behind following in JavaScript.
When I type in the Chrome console:
{} == null
it returns
Uncaught SyntaxError: Unexpected token ==
But
{} == {}
and
{} == function(){}
returns false
Why?
I have searched but could not find logic behind following in JavaScript.
When I type in the Chrome console:
{} == null
it returns
Uncaught SyntaxError: Unexpected token ==
But
{} == {}
and
{} == function(){}
returns false
Why?
I assume you understand why {} == null
throws SyntaxError
. Long story short it is because {
in the begining starting a block statement not an object literal. You could check the answer here
As of why {} == {}
this works.
If you check chromium code that evaluates expressions in console. You could find the following (code)
if (/^\s*\{/.test(text) && /\}\s*$/.test(text))
text = '(' + text + ')';
executionContext.evaluate(text, "console", !!useCommandLineAPI, false, false, true, printResult);
This code wraps {} == {}
code with parentheses making it a valid expression ({} == {})
comparing two empty object literals. Which evaluates to false
because objects are compared by reference.
Node repl has the same behaviour 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;
}
You can find this in the specs under Statement (art. 12)
Statement :
Block.
VariableStatement
EmptyStatement
ExpressionStatement
.
.
.
The first applicable rules are either Block or Expression Statement. So we need to look at 12.4.
In 12.4 the specs clearly state that an expression statement cannot start with a {
.
though i haven’t yet found what makes example 2 an expression, maybe it’s implementation specific
Syntax ExpressionStatement : [lookahead ∉ {{, function}] Expression ;
NOTE An ExpressionStatement cannot start with an opening curly brace because that might make it ambiguous with a Block. Also, an ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration.
Semantics The production ExpressionStatement : [lookahead ∉ {{, function}]Expression; is evaluated as follows:
Let exprRef be the result of evaluating Expression. Return (normal, GetValue(exprRef), empty).
I would say this is a parsing issue, rather than a logic issue per se.
In Chrome I get the observed behavior.
In IE I get syntax errors whenever I put {}
(or, it seems, any object literal) on the LHS of the ==
.
In both browsers, putting ()
around the expression fixed things. Or first assigning the object to a variable
var x = {}
x == null
I would say it seems to me like a bug in the parsing. Whether that is true in an academic sense would take digging through specs and grammars; the practical answer is, there are simple enough work-arounds that the best bet is to not do that.
It’s because JavaScript sucks The reason it doesn’t work is because JavaScript takes the type the comparison is taking from the first object.
For instance
3+”1” = 4
But
“3”+1 = 31
The first example does the operation as a number because the first object is a number The second example sees a string as the first object and treats the operation as concatenation of a string.
For your example {} is an object but null can’t be converted to an object
It works the other way because {} can be represented as a null object.