4

Using node 8.4.0:

$ node
> {x, y} = {x: 1, y: 2}
{ x: 1, y: 2 }
>

However, the following errors also non interactive: (the only diff is the semicolon)

$ node
> {x, y} = {x: 1, y: 2};
...

Also in Chrome console:

> {x,y} = {x:1, y:2}
< {x: 1, y: 2}
> {x,y} = {x:1, y:2};
x VM253:1 Uncaught SyntaxError: Unexpected token =

Can anyone explain this?

Clarification

This is not about let, var or cosnt destructuring which works as intended. This is about previously defined variables, (or non strict mode): from chrome console:

> let a, b;
< undefined
> [a, b] = [1, 2];
< >(2) [1, 2]
> a
< 1
> b
< 2
> {a, b} = {a:3, b:4}
< >{a: 3, b: 4}
> a
< 3
> b
< 4
> {a, b} = {a:3, b:4};
x VM1297:1 Uncaught SyntaxError: Unexpected token =
niry
  • 3,238
  • 22
  • 34
  • 4
    Surely you need a declarator keyword like `const`, `let`, or `var`. – Pointy Sep 07 '17 at 18:49
  • @Pointy, not correct if the variable was previously defined or not in strict mode. (no such problem with destructuring arrays, I use all the time) – niry Sep 07 '17 at 18:50
  • And yet adding it does in fact allow you to conclude the statement. – Paul Sep 07 '17 at 18:51
  • @paul, sure that is not the potential bug I'm pointing at. – niry Sep 07 '17 at 18:52
  • I'll clarify the question. – niry Sep 07 '17 at 18:53
  • 3
    You'll want to have a look at [Why is {} + {} no longer NaN in Chrome console?](https://stackoverflow.com/q/36438034/1048572), which explains how the semicolon-less statements get the parentheses they need to become valid (as per the answers below). – Bergi Sep 07 '17 at 19:39

2 Answers2

8

The proper syntax to destructure an object to existing variables is

({x, y} = {x: 1, y: 2});

This allows {x, y} = {x: 1, y: 2} to be an expression. Otherwise {x, y} is interpreted as a block with comma operator, this results in Unexpected token = error.

It works without parentheses and a semicolon in console because it is treated as an expression there. This is efficiently same thing as

console.log({x, y} = {x: 1, y: 2});
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
6

It is not a bug but by design. See "Assignment without declaration":

A variable can be assigned its value with destructuring separate from its declaration.

var a, b;
({a, b} = {a: 1, b: 2});

The ( .. ) around the assignment statement is required syntax when using object literal destructuring assignment without a declaration.

{a, b} = {a: 1, b: 2} is not valid stand-alone syntax, as the {a, b} on the left-hand side is considered a block and not an object literal.

However, ({a, b} = {a: 1, b: 2}) is valid, as is var {a, b} = {a: 1, b: 2}

Community
  • 1
  • 1
str
  • 42,689
  • 17
  • 109
  • 127