Destructuring object outside of var declaration

# Nathan Wall (4 years ago)

I'm wondering what the best syntax is for object destructuring outside of a var declaration. For instance, the following works in Firefox Nightly and Traceur:

var { a, b } = foo;

but the following doesn't:

var a, b;    { a, b } = foo;

I presume this is because in the second case the { a, b } is a block. However, the following does work:

var a, b;    ({ a, b }) = foo;

Is the above what people are expected to use (when they need to use destructuring outside of a var/let declaration or function arguments), or is there another form available?

# Brendan Eich (4 years ago)

Nathan Wall <mailto:nathan.wall at live.com> September 17, 2013 10:06 AM

Is the above what people are expected to use (when they need to use destructuring outside of a var/let declaration or function arguments), or is there another form available?

That's it. Lars Hansen originated destructuring for ES4 and implemented array patterns in Futhark (Opera's engine of the time), but not object patterns. His first proposal used

&{a: x, b: y} = foo

for just the reason you cite, but no one was keen on the ASI hazard (previous line must end with a semicolon). We cut the & pretty soon in ES4's evolution.

I say use var/let/const, it's better style; or else suffer a parentheses tax. This is pretty much a non-issue in practice, AFAICT.

# Brendan Eich (4 years ago)

Allen reminded me to mention that destructuring assignment, as opposed to binding, allows arbitrary LeftHandSideExpression in the patterns, as opposed to Identifiers. If someone wants to use that extravagence in an object pattern destructuring assignment, they can put parens around the whole thing.

# Axel Rauschmayer (4 years ago)

I say use var/let/const, it's better style; or else suffer a parentheses tax. This is pretty much a non-issue in practice, AFAICT.

I don’t think so, either. But error message could give appropriate hints, just in case (beyond the scope of TC39/ECMA-262, but still important, usability-wise).

# Thaddee Tyl (a year ago)

On Tue, Sep 17, 2013 at 4:27 PM, Brendan Eich <brendan at mozilla.com> wrote:

Nathan Wall <mailto:nathan.wall at live.com> September 17, 2013 10:06 AM I'm wondering what the best syntax is for object destructuring outside of a var declaration. For instance, the following works in Firefox Nightly and Traceur:

[…]

var a, b;
({ a, b }) = foo;

Is the above what people are expected to use (when they need to use destructuring outside of a var/let declaration or function arguments), or is there another form available?

That's it. Lars Hansen originated destructuring for ES4 and implemented array patterns in Futhark (Opera's engine of the time), but not object patterns. His first proposal used

&{a: x, b: y} = foo

for just the reason you cite, but no one was keen on the ASI hazard (previous line must end with a semicolon). We cut the & pretty soon in ES4's evolution.

I say use var/let/const, it's better style; or else suffer a parentheses tax. This is pretty much a non-issue in practice, AFAICT.

Have things evolved?

var foo, bar;
({foo, bar}) = {foo: 2, bar: 3};

is a "ReferenceError: invalid assignment left-hand side" in Firefox Nightly 51.0a2, and a "SyntaxError: Unexpected token (" in Google Chrome 54.0.2840.90.

var foo, bar;
{foo, bar} = {foo: 2, bar: 3};

is a "SyntaxError: expected expression, got '='" in Firefox, and it works in Google Chrome.

var extract = () => ({foo:1, bar:2});
var foo, bar;
{foo, bar} = extract();  // SyntaxError: expected expression, got

'=' in Firefox and Chrome ({foo, bar}) = extract(); // ReferenceError: invalid assignment left-hand side in Firefox, SyntaxError: Unexpected token ( in Chrome

I tried figuring out what the correct behaviour is from www.ecma-international.org/ecma-262/7.0/index.html#sec-destructuring-assignment, but the rabbit hole goes deep, so I have no idea who to file a bug with.

(Obviously, the "right" way to do it, ({foo, bar} = extract()), works in both Firefox and Chrome. They, hum, could use some better error messages, too, to guide users towards that.)

# Isiah Meadows (a year ago)

Firefox likely has a parser bug (it should never throw a ReferenceError in that situation).

As for the assignment, I wish that {foo, bar} = extract() was accepted as a statement in more places.

# Bob Myers (a year ago)

I thought it was

({x, y} = obj);
# Allen Wirfs-Brock (a year ago)

On Nov 13, 2016, at 10:49 AM, Isiah Meadows <isiahmeadows at gmail.com> wrote:

Firefox likely has a parser bug (it should never throw a ReferenceError in that situation).

FireFox is correct, Chrome is wrong. See the second early error rule at www.ecma-international.org/ecma-262/7.0/index.html#sec-assignment-operators-static-semantics-early-errors, www.ecma-international.org/ecma-262/7.0/index.html#sec-assignment-operators-static-semantics-early-errors

It is an early Reference www.ecma-international.org/ecma-262/7.0/index.html#sec-reference-specification-type Error if LeftHandSideExpression www.ecma-international.org/ecma-262/7.0/index.html#prod-LeftHandSideExpression is neither an ObjectLiteral www.ecma-international.org/ecma-262/7.0/index.html#prod-ObjectLiteral nor an ArrayLiteral www.ecma-international.org/ecma-262/7.0/index.html#prod-ArrayLiteral and IsValidSimpleAssignmentTarget of LeftHandSideExpression www.ecma-international.org/ecma-262/7.0/index.html#prod-LeftHandSideExpression is false.

# Isiah Meadows (a year ago)

Okay. Is it a spec bug then? Throwing a ReferenceError is surprising and odd IMHO.

# Boris Zbarsky (a year ago)

On 11/13/16 1:28 PM, Thaddee Tyl wrote:

var foo, bar;
{foo, bar} = {foo: 2, bar: 3};

is a "SyntaxError: expected expression, got '='" in Firefox, and it works in Google Chrome.

I get "Uncaught SyntaxError: Unexpected token =" in Chrome "56.0.2914.3 dev" and in Chrome "54.0.2840.9" (release).

# Claude Pache (a year ago)

Le 14 nov. 2016 à 22:53, Boris Zbarsky <bzbarsky at mit.edu> a écrit :

On 11/13/16 1:28 PM, Thaddee Tyl wrote: var foo, bar; {foo, bar} = {foo: 2, bar: 3};

is a "SyntaxError: expected expression, got '='" in Firefox, and it works in Google Chrome.

I get "Uncaught SyntaxError: Unexpected token =" in Chrome "56.0.2914.3 dev" and in Chrome "54.0.2840.9" (release).

-Boris

My guess is that Thaddee Tyl was confused by a Chrome DevTools feature, as in:

esdiscuss.org/topic/incosistency#content

# Boris Zbarsky (a year ago)

On 11/15/16 1:57 PM, Claude Pache wrote:

My guess is that Thaddee Tyl was confused by a Chrome DevTools feature, as in:

I considered that, but I actually got consistent results both in Chrome's console and in a webpage...

# Jeff Walden (10 months ago)

On 11/13/2016 12:33 PM, Isiah Meadows wrote:

Okay. Is it a spec bug then? Throwing a ReferenceError is surprising and odd IMHO.

I think so -- having different sorts of early errors makes it a little less clear what sort of error should be thrown when two early errors of different types are in the same script. Last I knew, the spec was basically just waiting on someone to experiment with pulling the trigger to make everything a SyntaxError. I've been meaning to do that for awhile, but it's not a high priority.