Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Babel's implementation of ES6 object destructuring correct?

So basic desctucturing is fine, {a, b} = obj transpiles to a = obj.a; b = obj.b.

My question is around a bit of an odd syntax that I accidentally ran across and I'm wondering if someone can point me at spec since I can't find it:

({a, b} = obj).c

That does the two a, b assignments and then returns obj.c. It's actually quite useful to me for a byte stream decoder, as I can write:

let width = ({bytes} = intDecode(bytes)).number;

My issue is that I haven't seen this syntax anywhere and don't want to rely on something that is either incorrectly implemented or in proposal stage.

like image 899
Nobody Avatar asked Sep 03 '15 06:09

Nobody


2 Answers

There is nothing special in Destructuring Assignment: it's evaluated as any other Assignment with = operator.

So it returns rval.

Which means you can rely on your syntax.

Some details:

The Destructuring Part is evaluated in the 6[1]:

Let status be the result of performing DestructuringAssignmentEvaluation of assignmentPattern using rval as the argument.

and after this item the assignment evaluation happens as usually, like in the a = b = 42; case.

References:

  • 12.14.4 Assignment Operators / Runtime Semantics: Evaluation
  • 12.14.5.2 Destructuring Assignment / Runtime Semantics: DestructuringAssignmentEvaluation
like image 162
zerkms Avatar answered Nov 07 '22 05:11

zerkms


Yes, it is expected to work like this (see @zerkms' answer for details). That you haven't seen the syntax anywhere is because it's not exactly good practice to access properties on the result of an assignment expression, as it makes the code quite unreadable. Whether you assign to a normal variable or a destructuring expression doesn't make much difference here.

However, you could quite easily transform the code into a reasonable destructuring assignment:

let {bytes, number:width} = intDecode(bytes);

or actually, more closely to your original code:

let width;
({bytes, number:width} = intDecode(bytes));
like image 41
Bergi Avatar answered Nov 07 '22 05:11

Bergi