23

In IE and Chrome, typing this into the JavaScript console throws an exception:

{} == false   // "SyntaxError: Unexpected token =="

However, all of these statements are evaluated with no problem:

false == {}   // false

({} == false) // false

var a = {};
a == false    // false

Is this intentional behavior? Why does this happen?

Jonn
  • 1,403
  • 1
  • 14
  • 24
  • 2
    Another oddity: [] == false // true – DexterW May 22 '14 at 01:54
  • @DexterW I was reading up on [truthy values](http://www.sitepoint.com/javascript-truthy-falsy/). Confusing stuff. – Jonn May 22 '14 at 01:55
  • Weird, `[] == false` is throwing me, but I feel like I've seen it before. **Edit:** [Aha!](http://stackoverflow.com/a/5491730/1883647) The array's `toString` method is secretly called, producing `''`, which is falsey! Correspondingly, `[] == ''` is `true`. – ajp15243 May 22 '14 at 02:00
  • 2
    Why does `function a() { b: 1 }` NOT throw an exception? –  May 22 '14 at 03:18
  • @torazaburo I would like to know. – Jonn May 22 '14 at 03:25
  • @torazaburo in `function a() { b: 1 }` the statement b: 1 is defining a label `b`. See this answer: http://stackoverflow.com/a/418865/99603 and the [EcmaScript spec section 12.12](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) – Benjamin Wegman May 22 '14 at 08:08
  • @BenjaminWegman Wow. Thanks for that. It's so strange that `{b: 1} == false` also throws an exception. I guess they have to get rid of ambiguity in the grammar one way or another... – Jonn May 22 '14 at 10:36
  • @Jonn I'm a little late coming back, but the `{ }` in torazaburo's `function` definition is *not* acting like the `{ }` in your `{b: 1} == false`. His is defining the function body block, whereas yours are the same as `{} == false` (a generic code block rather than an object). In your example, remember that (as Benjamin Wegman notes) `b: 1` is creating a *label* in your generic code block, and not an object property. – ajp15243 May 28 '14 at 14:40
  • Here's another interesting one: https://twitter.com/konklone/status/475819362172280833 – Jonn Jun 14 '14 at 13:30

1 Answers1

25

In the console, when you start a statement with {}, you are not creating an object literal, but a code block (i.e. the same block as you would make with an if statement or a loop body). A symbol like == is then obviously not expected afterwards.

If you think of a code block, you know that something like a = 5; could come after it:

if (some_condition) {
    // do something
}
a = 5;

You can then use this to test in the console, and find that it works just fine:

{} a = 5;
ajp15243
  • 6,951
  • 1
  • 29
  • 38
  • That is very, very interesting. So.. let me get this straight. I know that JavaScript functions, arrays, and objects are very similar. You can add properties/functions onto just about anything. Are code blocks (`{ ... }`) perceived differently? Why can you not compare a code block with an object? Or is that even the issue? – Jonn May 22 '14 at 02:06
  • @Jonn A code block isn't any sort of object or data model. It's just language syntax, and nothing more, meant to show an inline logical separation of code. It's weird here because it's legal to have code blocks not associated with any sort of language construct like `if` or `for` or `while` or `function()`. For instance, try `a=5; { b=6; } c=7;` in your console, and then see what the values of `a`, `b`, and `c` are. This goes back at least as far as C syntax rules, which allows independent code blocks. – ajp15243 May 22 '14 at 02:10
  • 1
    Thanks for your answer. You saved me some sleep. – Jonn May 22 '14 at 02:11
  • 1
    I think that should be "start a statement with…", but otherwise you're spot on. – RobG May 22 '14 at 02:15