数组解构
数组解构的语法看起来与对象解构非常相似,只是将对象字面量替换成了数组字面量。数组解构时,解构作用在数组内部的位置上,而不是作用在对象的具名属性上,例如:
let colors = [ "red", "green", "blue" ];
let [ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
此处数组解构从 colors
数组中取出了 "red"
与 "green"
,并将它们赋值给 fristColor
与 secondColor
变量。这些值被选择,是由于它们在数组中的位置,实际的变量名称是任意的(与位置无关)。任何没有在解构模式中明确指定的项都会被忽略。记住,数组本身并没有以任何方式被改变。
你也可以在解构模式中忽略一些项,并且只给感兴趣的项提供变量名。例如,若只想获取数组中的第三个元素,那么不必给前两项提供变量名。以下展示了这种方式:
let colors = [ "red", "green", "blue" ];
let [ , , thirdColor ] = colors;
console.log(thirdColor); // "blue"
此代码使用了解构赋值来获取 colors
的第三个项。模式中 thirdColor
之前的逗号,是为数组前面的项提供的占位符。使用这种方法,你就可以轻易从数组任意位置取出值,而无须给其他项提供变量名。
与对象解构相似,在使用 |
解构赋值
你可以在赋值表达式中使用数组解构,但是与对象解构不同,不必将表达式包含在圆括号内,例如:
let colors = [ "red", "green", "blue" ],
firstColor = "black",
secondColor = "purple";
[ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
此代码中解构赋值的工作方式与上例相似,唯一区别是 firstColor
与 secondColor
变量已经被声明过了。大多数情况下,以上可能就是数组解构赋值你需要了解的全部内容,但其实还有一个很细微却又可能很有用的用法。
数组解构赋值有一个非常独特的用例,能轻易地互换两个变量的值。互换变量值在排序算法中十分常用,而在 ES5
中需要使用第三个变量作为临时变量,正如下例:
// Swapping variables in ECMAScript 5
let a = 1,
b = 2,
tmp;
tmp = a;
a = b;
b = tmp;
console.log(a); // 2
console.log(b); // 1
其中的 tmp
变量对于互换 a
与 b
的值来说是必要的。然而若使用数组解构赋值,就不再需要这个额外变量。以下演示了在 ES6
中如何互换变量值:
// Swapping variables in ECMAScript 6
let a = 1,
b = 2;
[ a, b ] = [ b, a ];
console.log(a); // 2
console.log(b); // 1
本例中的数组解构赋值看起来如同镜像。赋值语句左侧(即等号之前)的解构模式正如其他数组解构的范例,右侧则是为了互换而临时创建的数组字面量。b 与 a 的值分别被复制到临时数组的第一个与第二个位置,并对该数组进行解构,结果两个变量就互换了它们的值。
与对象解构赋值相同,若等号右侧的计算结果为 |
默认值
数组解构赋值同样允许在数组任意位置指定默认值。当指定位置的项不存在、或其值为 undefined
,那么该默认值就会被使用。例如:
let colors = [ "red" ];
let [ firstColor, secondColor = "green" ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
此代码的 colors
数组只有一个项,因此没有能与 secondColor
匹配的项,又由于此处有个默认值,secondColor
的值就被设置为 "green"
,而不是 undefined
。
嵌套的解构
与解构嵌套的对象相似,可以用类似的方式来解构嵌套的数组。在整个解构模式中插入另一个数组模式,解构操作就会下行到嵌套的数组中,就像这样:
let colors = [ "red", [ "green", "lightgreen" ], "blue" ];
// later
let [ firstColor, [ secondColor ] ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
此处的 secondColor
变量指向了 colors
数组中的 "green"
值,该项被包含在第二个数组中,因此解构模式就要把 secondColor
包裹上方括号。与对象解构相似,你也能使用任意深度的数组嵌套。
剩余项
第三章介绍过函数的剩余参数,而数组解构有个类似的、名为剩余项(rest items)的概念,它使用 …
语法来将剩余的项目赋值给一个指定的变量,此处有个范例:
let colors = [ "red", "green", "blue" ];
let [ firstColor, ...restColors ] = colors;
console.log(firstColor); // "red"
console.log(restColors.length); // 2
console.log(restColors[0]); // "green"
console.log(restColors[1]); // "blue"
colors
数组的第一项被赋值给了 firstColor
变量,而剩余的则赋值给了一个新的 restColors
数组;restColors
数组则有两个项:"green"
与 "blue"
。若要取出特定项并要求保留剩余的值,则剩余项是非常有用的,但它还有另一个有用的功能。
方便地克隆数组在 JS
中是个明显被遗漏的功能。在 ES5
中开发者往往使用的是一个简单的方式,也就是用 concat()
方法来克隆数组,例如:
// cloning an array in ECMAScript 5
var colors = [ "red", "green", "blue" ];
var clonedColors = colors.concat();
console.log(clonedColors); //"[red,green,blue]"
尽管 concat()
方法的本意是合并两个数组,但不使用任何参数来调用此方法,就会获得原数组的一个克隆品。而在 ES6
中,你可以使用剩余项的语法来达到同样效果。实现如下:
// cloning an array in ECMAScript 6
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
console.log(clonedColors); //"[red,green,blue]"
在本例中,剩余项被用于将 colors
数组的值复制到 clonedColors
数组中。虽然从感觉上来说,使用这种技术未必让开发者复制数组的意图体现得比使用 concat()
方法更明显,但这依然是个值得关注的技巧。
剩余项必须是数组解构模式中最后的部分,之后不能再有逗号,否则就是语法错误。