数组解构和展开运算符
Array destructuring and spread operator
我不是 100% 清楚这段代码是如何工作的:
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
// OUTPUT: [0, 1, 2, 3, 4]
我正在使用 ...
运算符解构数组 a
。
我期待在第二行中进行大量作业。
x
将被赋值给 0,y
将被赋值给 ...a
(它将数组 a
中的元素作为单独的值传递)。
不过,我不清楚 ...a
是如何分配给 4 的。实际上,JS 在执行以下操作时会抛出异常:
...a = 4;
// Uncaught SyntaxError: Rest parameter may not have a default initializer
为什么这段代码输出修改后的数组,结尾为4
,而不是抛出异常?这究竟是如何工作的?
执行如下
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
[x, y, ...a ] = [0, 1, 2, 3, 4];
这意味着 RHS 数组中的第一个值分配给 x
,RHS 数组中的第二个值分配给 y
,其余值分配给 a
.
因此,x
的值为 0
,y
为 1
,a
为 [2, 3, 4]
...a
等于 .slice(start, end)
(左,解构)或 .concat(a)
(右,扩展):
[0, ...a, 4]
等于:
[0].concat(a).concat([4]) // [0,1,2,3,4]
鉴于:
[x, y, ...a] = array
等于:
x = array[0];
y = array[1];
a = array.slice(2);
It's not clear to me, though, how the ...a
get assigned to 4
.
不是。
让我们把事情分开一点:
在作业的右侧,您正在使用带有 展开元素 的数组文字。 a
的值是"flattened"到新数组中。
因此,[0, ...a, 4]
等同于 [0].concat(a, [4])
。结果是一个新数组。
var a = [1, 2, 3];
console.log('spread element', [0, ...a, 4]);
console.log('concat', [0].concat(a, [4]));
在左侧,您正在使用带有 剩余元素 的数组解构。 [x, y, ...a ]
表示
- 将可迭代对象的第一个值赋给
x
- 将可迭代对象的第二个值赋给
y
- 将可迭代的剩余值作为数组分配给
a
这两个是等价的:
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);
当然把这两者结合起来就可以了。在赋值中,左侧不关心右侧的计算方式,反之亦然。
您的示例令人困惑的是,您在解构赋值中再次使用 a
,但这与用新值覆盖 a
的值相同。然而最终的结果是
[0, ...a, 4]
结果是 [0,1,2,3,4]
因此
x
的值为 0
y
的值为 1
a
的值为 [2,3,4]
In fact, JS throws an exception when doing: ...a = 4;
您收到的错误消息很奇怪。这真的应该只是一个语法错误。
...
本身没有任何意义。它不是运算符,它是一个标点符号(如 ;
或 ,
),根据使用(和允许)的上下文具有不同的含义。
另见
在第一个示例中,传播即 ...
在 LHS 中充当收集器,而在 RHS 中它充当 spread/rest。 IE 你正在为变量 a
赋值,当它在 LHS 上时。
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
console.log(a)
让我们一步步来:
让我们从 RHS 开始。执行 [0, ...a, 4]
将生成 [0, 1, 2, 3, 4]
。自己看看:
var a = [1, 2, 3];
console.log([0, ...a, 4]);
现在,LHS
是进行分配的一侧。在 RHS 上,将任何带有扩展运算符的变量想象成一个 array
准备好分配新值。
因此,我们尝试将 [0, 1, 2, 3, 4]
分配给变量 x
,然后分配给 y
,其余分配给数组 a
(in该订单)。因此,数组 a
将拥有前两次赋值后剩下的任何内容(即 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);
最后,回到你的最后一个问题:"It's not clear to me, though, how the ...a get assigned to 4? "
答:不是。但是,如果您执行 [...a] = [4]
之类的操作,则会生成一个名为 a
的数组,其中包含 [4]
。
您可以阅读有关传播语法的更多信息 here (MDN) and here (YDKJS)。
我不是 100% 清楚这段代码是如何工作的:
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
// OUTPUT: [0, 1, 2, 3, 4]
我正在使用 ...
运算符解构数组 a
。
我期待在第二行中进行大量作业。
x
将被赋值给 0,y
将被赋值给 ...a
(它将数组 a
中的元素作为单独的值传递)。
不过,我不清楚 ...a
是如何分配给 4 的。实际上,JS 在执行以下操作时会抛出异常:
...a = 4;
// Uncaught SyntaxError: Rest parameter may not have a default initializer
为什么这段代码输出修改后的数组,结尾为4
,而不是抛出异常?这究竟是如何工作的?
执行如下
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
[x, y, ...a ] = [0, 1, 2, 3, 4];
这意味着 RHS 数组中的第一个值分配给 x
,RHS 数组中的第二个值分配给 y
,其余值分配给 a
.
因此,x
的值为 0
,y
为 1
,a
为 [2, 3, 4]
...a
等于 .slice(start, end)
(左,解构)或 .concat(a)
(右,扩展):
[0, ...a, 4]
等于:
[0].concat(a).concat([4]) // [0,1,2,3,4]
鉴于:
[x, y, ...a] = array
等于:
x = array[0];
y = array[1];
a = array.slice(2);
It's not clear to me, though, how the
...a
get assigned to4
.
不是。
让我们把事情分开一点:
在作业的右侧,您正在使用带有 展开元素 的数组文字。 a
的值是"flattened"到新数组中。
因此,[0, ...a, 4]
等同于 [0].concat(a, [4])
。结果是一个新数组。
var a = [1, 2, 3];
console.log('spread element', [0, ...a, 4]);
console.log('concat', [0].concat(a, [4]));
在左侧,您正在使用带有 剩余元素 的数组解构。 [x, y, ...a ]
表示
- 将可迭代对象的第一个值赋给
x
- 将可迭代对象的第二个值赋给
y
- 将可迭代的剩余值作为数组分配给
a
这两个是等价的:
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);
当然把这两者结合起来就可以了。在赋值中,左侧不关心右侧的计算方式,反之亦然。
您的示例令人困惑的是,您在解构赋值中再次使用 a
,但这与用新值覆盖 a
的值相同。然而最终的结果是
[0, ...a, 4]
结果是[0,1,2,3,4]
因此x
的值为0
y
的值为1
a
的值为[2,3,4]
In fact, JS throws an exception when doing:
...a = 4;
您收到的错误消息很奇怪。这真的应该只是一个语法错误。
...
本身没有任何意义。它不是运算符,它是一个标点符号(如 ;
或 ,
),根据使用(和允许)的上下文具有不同的含义。
另见
在第一个示例中,传播即 ...
在 LHS 中充当收集器,而在 RHS 中它充当 spread/rest。 IE 你正在为变量 a
赋值,当它在 LHS 上时。
var a = [1, 2, 3];
[x, y, ...a ] = [0, ...a, 4];
console.log(a)
让我们一步步来:
让我们从 RHS 开始。执行 [0, ...a, 4]
将生成 [0, 1, 2, 3, 4]
。自己看看:
var a = [1, 2, 3];
console.log([0, ...a, 4]);
现在,LHS
是进行分配的一侧。在 RHS 上,将任何带有扩展运算符的变量想象成一个 array
准备好分配新值。
因此,我们尝试将 [0, 1, 2, 3, 4]
分配给变量 x
,然后分配给 y
,其余分配给数组 a
(in该订单)。因此,数组 a
将拥有前两次赋值后剩下的任何内容(即 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);
最后,回到你的最后一个问题:"It's not clear to me, though, how the ...a get assigned to 4? "
答:不是。但是,如果您执行 [...a] = [4]
之类的操作,则会生成一个名为 a
的数组,其中包含 [4]
。
您可以阅读有关传播语法的更多信息 here (MDN) and here (YDKJS)。