解构赋值是一种用来将数据结构(如数组、对象、Set、Map等)中的值提取出来并赋值给变量的语法。
语法
解构赋值的语法包括两个部分:解构的模式和赋值的表达式。解构的模式指定了需要提取的值的结构,可以是数组、对象、Set、Map等。赋值的表达式则指定了需要将提取出来的值赋给哪些变量。解构赋值的基本语法如下:
数组解构赋值
let [a, b, c] = [1, 2, 3];
上面的代码将数组 [1, 2, 3] 解构成三个变量 a、b、c,并分别赋值为 1、2、3。这相当于如下的赋值语句:
let a = 1;
let b = 2;
let c = 3;
如果数组中的元素不足以提供所有的变量,那么没有对应的变量将被赋值为 undefined。
对象解构赋值
let {name, age} = {name: 'Alice', age: 30};
上面的代码将对象 {name: 'Alice', age: 30} 解构成两个变量 name 和 age,并分别赋值为 'Alice' 和 30。这相当于如下的赋值语句:
let name = 'Alice';
let age = 30;
如果需要使用不同的变量名来访问对象属性,可以使用“键值对”的语法来指定变量名和属性名的对应关系。
let {name: n, age: a} = {name: 'Alice', age: 30};
上面的代码将对象 {name: 'Alice', age: 30} 解构成两个变量 n 和 a,并分别赋值为 'Alice' 和 30。
嵌套解构赋值
解构赋值也可以用来提取嵌套数据结构中的值。例如:
let {name, age, address: {city, street}} = {
name: 'Alice',
age: 30,
address: {
city: 'Shanghai',
street: 'Nanjing Road'
}
};
上面的代码将对象 {name: 'Alice', age: 30, address: {city: 'Shanghai', street: 'Nanjing Road'}} 解构成三个变量 name、age 和 city、street。其中,address 是一个嵌套对象,可以使用 address: {city, street} 的语法来提取其中的属性。最终的结果是:
let name = 'Alice';
let age = 30;
let city = 'Shanghai';
let street = 'Nanjing Road';
Set 和 Map 解构赋值
除了数组和对象之外,Set 和 Map 也支持解构赋值。
对于 Set,解构赋值将从 Set 中按顺序提取元素,并赋值给对应的变量。例如:
let set = new Set(['red', 'green', 'blue']);
let [a, b, c] = set;
上面的代码将 Set {red, green, blue} 解构成三个变量 a、b、c,并分别赋值为 'red'、'green'、'blue'。
对于 Map,解构赋值将从 Map 中按顺序提取键值对,并将键和值分别赋值给对应的变量。例如:
let map = new Map([['name', 'Alice'], ['age', 30]]);
let [[k1, v1], [k2, v2]] = map;
上面的代码将 Map {name => 'Alice', age => 30} 解构成四个变量 k1、v1、k2、v2,并分别赋值为 'name'、'Alice'、'age'、30'。这里需要注意的是,Map 中的键值对也是一个数组,因此需要使用两层解构。
用法
交换变量的值
解构赋值可以用来快速交换两个变量的值,而不需要使用临时变量。例如:
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
上面的代码交换了变量 a 和 b 的值,不需要使用临时变量。
从函数返回多个值
函数只能返回一个值,但是使用解构赋值可以返回多个值。例如:
function getData() {
return [1, 2, 3];
}
let [a, b, c] = getData();
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
上面的代码从函数中返回了三个值,然后使用解构赋值将这三个值分别赋值给变量 a、b 和 c。这样做的好处是可以在一次函数调用中获取多个值,而不需要使用多个变量来接收这些值。
提取函数参数中的属性
在函数的参数中可以使用解构赋值来提取对象中的属性。例如:
function printUser({name, age, address}) {
console.log(`${name} (${age}) - ${address.city}, ${address.street}`);
}
let user = {
name: 'Alice',
age: 30,
address: {
city: 'Shanghai',
street: 'Nanjing Road'
}
};
printUser(user);
// 输出:Alice (30) - Shanghai, Nanjing Road
上面的代码定义了一个函数 printUser,它的参数是一个对象,其中包含了用户的姓名、年龄和地址。使用解构赋值将这些属性分别赋值给变量 name、age 和 address,然后打印出用户的信息。
简化对象的写法
在创建对象时,可以使用解构赋值来简化属性的写法。例如:
let name = 'Alice';
let age = 30;
let address = {
city: 'Shanghai',
street: 'Nanjing Road'
};
let user = {name, age, address};
console.log(user);
// 输出:{name: 'Alice', age: 30, address: {city: 'Shanghai', street: 'Nanjing Road'}}
上面的代码将变量 name、age 和 address 分别赋值给对象 user 的同名属性,从而简化了对象的写法。
接收剩余的元素
解构赋值可以使用扩展运算符 ... 来接收剩余的元素。例如:
let [a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(rest); // [3, 4, 5]
上面的代码使用解构赋值将数组 [1, 2, 3, 4, 5] 分别赋值给变量 a、b 和 rest。由于 rest 前面使用了扩展运算符 ...,因此它会接收数组中剩余的元素,并将它们放入一个新数组中。
默认值
解构赋值可以给变量设置默认值,当被赋值的值为 undefined 时,会使用默认值。例如:
let {name = 'Anonymous', age = 18} = {name: 'Alice'};
console.log(name); // Alice
console.log