admin管理员组文章数量:1410737
It's not 100% clear to me how this piece of code works:
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
// OUTPUT: [0, 1, 2, 3, 4]
I'm deconstructing the array a
using the ...
operator.
I am expecting that in second line a bunch of assignments will take place.
The x
will be assigned to 0, y
will be assigned to ...a
(which passes the elements in the array a
as individual values).
It's not clear to me, though, how the ...a
get assigned to 4. In fact, JS throws an exception when doing:
...a = 4;
// Uncaught SyntaxError: Rest parameter may not have a default initializer
Why does this code output the modified array with the end 4
, instead of throwing an exception? How does this work exactly?
It's not 100% clear to me how this piece of code works:
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
// OUTPUT: [0, 1, 2, 3, 4]
I'm deconstructing the array a
using the ...
operator.
I am expecting that in second line a bunch of assignments will take place.
The x
will be assigned to 0, y
will be assigned to ...a
(which passes the elements in the array a
as individual values).
It's not clear to me, though, how the ...a
get assigned to 4. In fact, JS throws an exception when doing:
...a = 4;
// Uncaught SyntaxError: Rest parameter may not have a default initializer
Why does this code output the modified array with the end 4
, instead of throwing an exception? How does this work exactly?
-
2
...
is not an operator! – Felix Kling Commented Jul 12, 2018 at 17:15 -
2
"how the
...a
get assigned to4
" It does not. What makes you think that? The output you are seeing is the result of evaluating[0, ...a, 4]
.[x, y, ...a ] = foo
means "assign the first value of the iterablefoo
tox
, the second one toy
and the remaining ones as an array toa
". – Felix Kling Commented Jul 12, 2018 at 17:16 -
I see. Now makes sense why the output of
a
is[2, 3, 4]
. – leonardofed Commented Jul 12, 2018 at 17:21
4 Answers
Reset to default 4It is executed like following
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
[x, y, ...a ] = [0, 1, 2, 3, 4];
which means first value in RHS array is assigned to x
, second value in RHS array is assigned to y
and the remaining values are assigned to a
.
Hence, value of x
is 0
, y
is 1
and a
is [2, 3, 4]
It's not clear to me, though, how the
...a
get assigned to4
.
It's not.
Lets split things up a little:
On the right hand side of the assignment you are using an array literal with a spread element. The value of a
is "flattened" into the new array.
Thus, [0, ...a, 4]
is is equivalent to [0].concat(a, [4])
. The result is a new array.
var a = [1, 2, 3];
console.log('spread element', [0, ...a, 4]);
console.log('concat', [0].concat(a, [4]));
On the left hand side you are using array destructuring with a rest element. [x, y, ...a ]
means
- assign the first value of the iterable to
x
- assign the second value of the iterable to
y
- assign the remaining values of the iterable as an array to
a
These two are equivalent:
var a = [1,2,3,4];
var [x, y, ...z] = a;
console.log('destructuring', x, y, z);
var x = a[0];
var y = a[1];
var z = a.slice(2);
console.log('manual + slice', x, y, z);
Of course bining these two is perfectly fine. In an assignment, the left hand side doesn't care what how the right hand side is puted and vice versa.
What's confusing about your example is that you are using a
again in the destructuring assignment, but that's the same as overriding the value of a
with a new value. However the end result is
[0, ...a, 4]
results in[0,1,2,3,4]
thereforx
has value0
y
has value1
a
has value[2,3,4]
In fact, JS throws an exception when doing:
...a = 4;
The error message you are getting is strange. It should really be just a syntax error.
...
by itself doesn't mean anything. It's not an operator, it's a punctuator (like ;
or ,
) that has a different meaning depending on the context it is used (and allowed).
See also What is SpreadElement in ECMAScript documentation? Is it the same as Spread operator at MDN?
...a
is either equal to .slice(start, end)
(left, destructuring) or to .concat(a)
(right, spreading):
[0, ...a, 4]
is equal to:
[0].concat(a).concat([4]) // [0,1,2,3,4]
Whereas:
[x, y, ...a] = array
Is equal to:
x = array[0];
y = array[1];
a = array.slice(2);
In the first example, spread ie ...
in LHS acts as gatherer whereas on the RHS it acts as spread/rest. IE you are assigning value to variable a
when it is on LHS.
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
console.log(a)
Let's go step by step:
Let's start with RHS. Doing [0, ...a, 4]
will generate [0, 1, 2, 3, 4]
. See for yourself:
var a = [1, 2, 3];
console.log([0, ...a, 4]);
Now, the LHS
is the side where assignment is taking place. On RHS, imagine any variable with spread operator as an array
ready to be assigned new values.
So, we are trying to assign [0, 1, 2, 3, 4]
to a variable x
, then to y
and the rest to array a
(in that order). So, array a
will have whatever will be left after first two assignments (ie 2, 3, 4
).
var a = [1, 2, 3];
// a will get overwritten
[x, y, ...a ] = [0, 1, 2, 3, 4];
// same as [x, y, ...a ] = [0, ...a, 4];
console.log(a);
Finally, ing to your last question: "It's not clear to me, though, how the ...a get assigned to 4? "
Answer: It is not. But if you do something like [...a] = [4]
, it will result in an array named a
containing [4]
.
You can read more about spread syntax here (MDN) and here (YDKJS).
本文标签: javascriptArray destructuring and spread operatorStack Overflow
版权声明:本文标题:javascript - Array destructuring and spread operator - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744850113a2628443.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论