JavaScript 中使用数组解构

Posted by cl9000 on July 09, 2020

在事情成功之前,一切总看似不可能。——<纳尔逊·曼德拉>

作者:Ashish Lahoti
译者:cl9000
来源:https://codingnconcepts.com/javascript/array-destructuring/

在本教程中,我们将通过示例来学习 JavaScript ES6 中数组解构的用法。

解构分配是JavaScript ES6中引入的一种特殊语法,它使我们可以在单个语句中从数组或对象中提取多个项目并将它们分配给变量。

1. 基本阵列解构

我们可以从数组中提取多个元素,然后在单个语句中使用数组解构将它们分配给变量。

与我们将元素逐一分配给变量的传统方式相比,数组解构的简写语法非常方便。

1
2
3
4
5
6
7
8
9
10
11
const numbers = [1, 2, 3];

//const one = numbers[0]; //传统方式
//const two = numbers[1];
//const three = numbers[2];

const [one, two, three] = numbers; //Array Destructuring 数组解构

console.log(one); //1
console.log(two); //2
console.log(three); //3

我们还可以在赋值之前声明变量:

1
2
3
4
5
6
7
8
let one, two, three;
const numbers = [1, 2, 3];

[one, two, three] = numbers;

console.log(one); //1
console.log(two); //2
console.log(three); //3

或者我们可以内联声明它们:

1
2
3
4
5
const [one, two, three] = [1, 2, 3];

console.log(one); //1
console.log(two); //2
console.log(three); //3

2. 默认值

我们可以为未定义或不存在的数组元素提供默认值。

1
2
3
4
5
6
7
8
const numbers = [1, undefined, 3];

const [one = "I", two = "II", three = "III", four = "IV"] = numbers;

console.log(one); //1
console.log(two); //II <- default value since 'undefined'
console.log(three); //3
console.log(four); //IV <- default value since doesn't exist

我们看到第二个元素是未定义的,第四个元素不存在。在这两种情况下,均将默认值分配给变量。

3. 嵌套数组解构

我们还可以执行嵌套数组解构以从嵌套数组中获取更深层次的元素:

1
2
3
4
5
6
7
const numbers = [1, 2, [9, 10, [11, 12]]];

const [one, two, [nine, ten, [eleven, twelve]]] = numbers

console.log(one) //1
console.log(nine) //9
console.log(eleven) //11

嵌套数组解构的另一种方法是使用ES9 Array.flat()方法,该方法将嵌套数组展平为普通数组:

1
2
3
4
5
6
7
8
9
const numbers = [1, 2, [9, 10, [11, 12]]];

const flattenNumbers = numbers.flat().flat();

const [one, two, nine, ten, eleven, twelve] = flattenNumbers;

console.log(one) //1
console.log(nine) //9
console.log(eleven) //11

请注意,该 Array.flat() 方法将嵌套数组的深度展平了一层。这就是为什么我们两次调用此方法numbers.flat().flat() 以在两个层次上展平。

另请注意,Array.flat() 方法是 Array.flatMap() 方法的缩写,两者的工作原理相同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const numbers = [1, 2, [9, 10, [11, 12]]];

const flat = numbers.flat();
const flatMap = numbers.flatMap(x => x);

console.log(flat); // [1, 2, 9, 10, [11, 12]]
console.log(flatMap); // [1, 2, 9, 10, [11, 12]]

// flatten one more level deeper
const flatDeep = flat.flat();
const flatMapDeep = flatMap.flatMap(x => x);

console.log(flatDeep); // [1, 2, 9, 10, 11, 12]
console.log(flatMapDeep); // [1, 2, 9, 10, 11, 12]

4. 使用逗号跳过元素

我们还可以使用 逗号分隔符 来跳过某些元素。让我们获取数组的第一个和第四个元素:

1
2
3
4
let [one, , , four] = [1, 2, 3, 4];

console.log(one); //1
console.log(four); //4

这里 , , ,数组解构中的两个额外的逗号分隔符会跳过第二个和第三个元素。同样,让我们​​跳过第一个和第三个元素:

1
2
3
4
let [ , two , , four] = [1, 2, 3, 4];

console.log(two); //2
console.log(four); //4

5. 剩余元素

我们还可以使用 rest运算符 … 从数组中获取其余元素,如下所示:

1
2
3
4
5
6
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const [one, two, three, ...others] = numbers;
console.log(one); //1
console.log(two); //1
console.log(three); //1
console.log(others); //[4, 5, 6, 7, 8, 9]

请注意,**rest运算符…**始终最后使用,否则会引发错误。

6. Rest 和 Spread 运算符

我们经常会混淆 RestSpread 运算符,因为它们都使用相同的 ... 语法。RestSpread 运算符可以在 Array Destructuring 语句中一起使用:

  • Rest 操作符: 在语句的 左边 使用,用于从数组获取剩余属性
  • Spread 操作符: 在语句的 右侧 使用,用于将属性复制到数组中
1
2
3
4
5
6
7
8
9
10
11
12
const tens      = [10, 20, 30];
const hundreds = [100, 200];
const thousands = [1000];

// Rest operator // Spread Operator
const [one, two, ten, twenty, ...others] = [1, 2, ...tens, ...hundreds, ...thousands];;

console.log(one); //1
console.log(two); //2
console.log(ten); //10
console.log(twenty); //20
console.log(others); //[30, 100, 200, 1000]

7. 解构返回语句

我们可以通过以下方式使用数组解构从函数返回的数组中提取数据:

1
2
3
4
5
6
7
8
function getNumberArray() {
return [1, 2, 3, 4, 5];
}

var [one, ...others] = getNumberArray();

console.log(one); //1
console.log(others); //[2, 3, 4, 5]

8. 解构函数参数

我们甚至可以将数组传递给函数,然后使用 Array Destructuring 以这种方式仅提取我们想要的元素:

1
2
3
4
5
6
7
8
const numbers = [1, 2, 3, 4, 5];

function getNumberArray( [ one, ...others ] ) {
console.log(one); //1
console.log(others); //[2, 3, 4, 5]
}

getNumberArray(numbers);

9. 实际用例

9.1. 内部for-of循环

1
2
3
4
5
6
7
8
9
我们可以通过以下方式在内部循环中使用数组解构for-of

const numbers = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ];
for (let [ a, b, c ] of numbers) {
console.log(a, b, c);
}
// 1 2 3
// 4 5 6
// 7 8 9

9.2. 内部forEach功能

我们可以使用数组解构轻松地遍历对象。

1
2
const obj = { foo: 'bar', baz: 42 };
Object.entries(obj).forEach(([key, value]) => console.log(`${key}: ${value}`)); // "foo: bar", "baz: 42"

我们看到 Object.entries 返回带有键值对的数组,该数组是使用 [key, value] 解构方法提取的。

9.3. 内部Map迭代

我们也可以使用 [key, value] 解构来解构 Map 的键值对。

1
2
3
4
5
6
7
8
9
var map = new Map();
map.set("one", 1);
map.set("two", 2);

for (var [key, value] of map) {
console.log(key + " is " + value);
}
// one is 1
// two is 2

仅迭代键:

1
2
3
for (var [key] of map) {
// ...
}

或仅迭代值:

1
2
3
for (var [,value] of map) {
// ...
}

9.4. 交换值

使用数组解构交换值非常有趣:

1
2
3
4
5
6
7
let one = 1;
let two = 2;

[one, two] = [two, one];

console.log(one); //2
console.log(two); //1

9.5. 正则表达式

正则表达式函数(例如,match 返回匹配项的数组)可以使用 Array Destructuring 映射到变量:

1
2
3
const [a, b, c, d] = 'one two three'.match(/\w+/g);

// a = 'one', b = 'two', c = 'three', d = undefined

参考

关注【公众号】,了解更多。
关注【公众号】,了解更多。
关注【公众号】,了解更多。



支付宝打赏 微信打赏

赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!