DEV Community

loading...
Cover image for What is {x:1} and why does it return 1 🤷‍♂️

What is {x:1} and why does it return 1 🤷‍♂️

h43z profile image h43z ・3 min read

Recently I came across what I found to be weird behavior when you type {x:1} into the respective browser developer tools (Chrome and Firefox).

It took me by surprise that Firefox returned 1. I was expecting the same response as I got in chrome namely {x:1} nicely formatted and with all the usual prototype stuff.

After some digging I think I finally figured out what's going on.

Let's go over it step by step.

First one thing to make clear {x:1} is actually not JSON as keys in JSON need to be wrapped in double quotes. (And even JSON is not considered valid javascript code)

Technically we never deal with JSON in javascript anyway except when it's in a string literal like '{ "x" : 1 }' and we feed it to JSON.parse or whatever.

Programmers mostly deal with object literals like const obj = {x:1}.

But {x:1} on its own is not an object literal. In fact it's something totally different.

If you dissect {x:1} you will see the outer part is actually a block statement.

Alt Text

A block statement (or compound statement in other languages) is used to group zero or more statements.

And within you have what's called a labeled statement

Alt Text

A labeled statement is very uncommon and not that useful. It kind of acts like a GOTO. But you can only jump to a label with a continue or break command.

loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}
Enter fullscreen mode Exit fullscreen mode

You see with the example {x:1}, x is the label name and 1 is the statement. Statements when entered into the web console are simply returned.

And that is why Firefox prints 1 when you type {x:1} into the console.

If you dig into MDN you will stumble upon this warning on object literals.

Alt Text

Okay we learned this the hard way and by detour.

But why does {x:1} do what 99.9% of developers would expect when typed into google chromes developer tools?

And the answer can be found in the source code of the actual web console.

Alt Text

souce

Chrome assumes that most developers mean to input object literals into the web console so it does a little trick.

It wraps {} with () aka the javascript grouping operator.

The grouping operator consists of a pair of parentheses around an expression or sub-expression to override the normal operator precedence so that expressions with lower precedence can be evaluated before an expression with higher priority. As it sounds, it groups what's inside of the parentheses.

So in the end what chrome executes is ({x:1}). And that for some reason still not fully clear to me (enlighten me in the comments!) turns the labeled statement within a block statement into a object literal.

And with Firefox you just have to do this manually.

Alt Text

I hope you enjoyed this investigation like I did and make sure to follow me on twitter @h43z for more goofing around.

Discussion (8)

pic
Editor guide
Collapse
jcubic profile image
Jakub T. Jankiewicz

You may think that this actually doesn't matter much, because it never happen in real code, but this is really important for arrow functions:

const fn = () => {x: 1};
Enter fullscreen mode Exit fullscreen mode

this is a function that return undefined not object, because it's block with label and no return.

Collapse
h43z profile image
h43z Author

ohhh... good to know. Thank you!

Collapse
patarapolw profile image
Pacharapol Withayasakpunt

Good linters will tell.

Collapse
jcubic profile image
Jakub T. Jankiewicz

This is what ESLint will tell you, you got errors but you may have no clue what they mean:

  5922:39  error  'x:' is defined but never used                    no-unused-labels
  5922:39  error  This line has 2 statements. Maximum allowed is 1  max-statements-per-line
  5922:42  error  Missing semicolon                                 semi
Enter fullscreen mode Exit fullscreen mode
Collapse
shrihankp profile image
Shrihan Kumar Padhy

Firefox does a very good job to execute the JavaScript as it would in a JavaScript file. Chrome's implementation is Ok, if you're quickly prototyping something(and maybe, you're lazy 😂), but this hides what the actual thing is.

Collapse
joas8211 profile image
Jesse Sivonen

Please correct me if I'm wrong. Parentheses turn the example labeled statement into object literal because grouping operator is an expression that cannot contain statements. Only blocks can contain statements. Statements are constructs that cannot be assigned into a variable where as expressions can.

Collapse
jonathanalberghini profile image
Collapse
aminmansuri profile image
hidden_dude

I didn't realize Javascript had labels.

How are labels used in JavaScript?

Is there somthing like:

LABEL:
while (...) { 
   ...
   break LABEL;
}
Enter fullscreen mode Exit fullscreen mode

Like in Java?