2

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?

Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
dhaker
  • 1,605
  • 18
  • 19

4 Answers4

4

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;
}
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
1

You can find this in the specs under Statement (art. 12)

12 - Statement

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

12.4 Expression Statement

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).

Moritz Roessler
  • 8,542
  • 26
  • 51
0

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.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • In that case why it does not have problem parsing `{} == {}` – dhaker Jun 22 '18 at 13:54
  • As I said, it may be a bug (in which case there's no sense trying to reason about "why"), If it's not, then given that different browsers behave differently (IE *does*, in fact, have a problem parsing `{} == {}`), it must fall into a category of undefined behaviors (in which case there's no sense trying to reason about "why"). I don't believe it matters *why*. It is observed to occur, and there are easy ways to work around it – Mark Adelsberger Jun 22 '18 at 14:15
  • Adding info from Yury's answer as context, I will clarify that slightly. The behavior in Chrome of *not* throwing an error is either a deliberately designed-in deviation from the spec (which is a bug whether or not its intent is benign) or a case where the spec gave enough flexibility to do, or not do, what Chrome has chosen to do (essentially an undefined behavior). The fact that it makes the behavior appear less consistent and harder to predict is why I don't agree with it, and wouldn't intentionally write JS code that takes advantage of it. – Mark Adelsberger Jun 22 '18 at 14:24
-4

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.