I was checking out node.green and under destructuring, assignment > nested rest, the following example function is used:
function f() {
var a = [1, 2, 3], first, last;
[first, ...[a[2], last]] = a;
return first === 1 && last === 3 && (a + "") === "1,2,2";
}
console.log(f())
Now, I understand destructuring but I cannot figure out why how a
was rewritten to [1, 2, 2]
Also [...[a[2], last]] = a;
returns [1, 2, 1]
[first, a[2], last] = a;
is like
// first == undefined, last == undefined, a == [1,2,3]
first = a[0];
// first == 1, last == undefined, a == [1,2,3]
a[2] = a[1];
// first == 1, last == undefined, a == [1,2,2]
last = a[2];
// first == 1, last == 2, a == [1,2,2]
[first, ...[a[2], last]] = a;
is like
// first == undefined, last == undefined, a == [1,2,3], tmp == undefined
first = a[0];
// first == 1, last == undefined, a == [1,2,3], tmp == undefined
tmp = [a[1], a[2]];
// first == 1, last == undefined, a == [1,2,3], tmp == [2,3]
a[2] = tmp[0];
// first == 1, last == undefined, a == [1,2,2], tmp == [2,3]
last = tmp[1];
// first == 1, last == 3, a == [1,2,2], tmp == [2,3]
[...[a[2], last]] = a;
is like
// last == undefined, a == [1,2,3], tmp == undefined
tmp = [a[0], a[1]];
// last == undefined, a == [1,2,3], tmp == [1,2]
a[2] = tmp[0];
// last == undefined, a == [1,2,1], tmp == [1,2]
last = tmp[1];
// last == 2, a == [1,2,1], tmp == [1,2]
In the second line, you are setting a[2]
to whatever is the second value of a
, i.e. a[1]
, which in this case is 2
.
Interestingly, if you change [first, ...[a[2], last]]
to [first, a[2], last]
, last
becomes 2 (the final values of first
and a
are the same as in your example):
var a = [1, 2, 3], first, last;
[first, a[2], last] = a;
console.log(first === 1);
console.log(a + '' === '1,2,2');
console.log(last === 2);
It looks like a[2]
is being assigned the value 2
first, then last
is being assigned the value of a[2]
. In your example, it seems the old values of a
are being kept. I suspect this is because ...
creates an intermediate array, whose values are then being assigned to a[2]
and last
. Hopefully someone who knows the deep parts of the ES6 spec can confirm, but presumably that is the reason for the more convoluted [first, ...[a[2], last]]
.
Bergi shared a spec reference in the comments:
see IteratorBindingInitialization, with BindingRestElement. However, the usage of a BindingPattern instead of a simple BindingIdentifier is actually new in ES7. In ES6 you'd need to write var [first, ...tmp] = a; [a[2], last]] = tmp; which makes clearer what is happening.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With