ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。解构赋值是一种从数组或对象中提取值并赋给变量的语法,它可以简化代码,使得对多个变量的赋值更加便捷和直观。而且可以减少冗余代码,提高代码的可读性和可维护性。
数组解构赋值的语法使用方括号 [] 来表示要解构的数组,然后通过等号(=)将解构的值赋给变量。
数组解构赋值允许我们通过类似于数组字面量的语法,将数组中的元素解构到多个变量中。在数组解构赋值中,我们可以使用方括号 [] 来表示数组,通过将变量放在方括号中,就可以将数组中对应位置的元素赋给这些变量。基本用法如下所示:
let [a, b, c] = [1, 2, 3];
上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值就等于undefined。
let [foo] = [];
let [bar, foo] = [1];
以上两种情况都属于解构不成功,foo的值都会等于undefined。另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
let [x, y] = [1, 2, 3];
console.log(x); // 1
console.log(y); // 2
let [a, [b], d] = [1, [2, 3], 4];
console.log(a); // 1
console.log(b); // 2
console.log(d); // 4
在解构赋值时,我们可以为变量指定默认值,当数组中对应位置的值不存在或为 undefined 时,就会使用默认值。
let [a, b = 0, c] = [1, , 3];
console.log(a); // 1
console.log(b); // 0
console.log(c); // 3
注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined。如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。
在数组解构赋值中,我们还可以使用剩余参数 … 来获取数组中剩余的元素。
let [a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(rest); // [3, 4, 5]
解构不仅可以用于数组,还可以用于对象。对象解构赋值允许我们通过类似于对象字面量的语法,将对象中的属性解构到多个变量中。在对象解构赋值中,我们可以使用花括号 {} 来表示对象,通过将变量放在花括号中,就可以将对象中对应属性的值赋给这些变量。
let {name, age} = {name: 'Alice', age: 20};
console.log(name); // Alice
console.log(age); // 20
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
console.log(foo); // "aaa"
console.log(bar); // "bbb"
let { baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz); // undefined
上面代码的第一个例子,等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响。第二个例子的变量没有对应的同名属性,导致取不到值,最后等于undefined
。如果解构失败,变量的值等于undefined
。
在解构赋值时,我们可以为变量指定默认值,当对象中对应属性的值不存在或为undefined时,就会使用默认值。
let {name, age = 0} = {name: 'Alice'};
console.log(name); // Alice
console.log(age); // 0
默认值生效的条件是,对象的属性值严格等于
undefined
,null
与undefined
不严格相等。
在对象解构赋值中,我们还可以使用剩余参数 … 来获取除已解构属性外的其它属性。
let {name, ...rest} = {name: 'Alice', age: 20, gender: 'female'};
console.log(name); // Alice
console.log(rest); // {age: 20, gender: 'female'}
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
console.log(a); // "h"
console.log(b); // "e"
console.log(c); // "l"
console.log(d); // "l"
console.log(e); // "o"
类似数组的对象都有一个length
属性,因此还可以对这个属性解构赋值。
let {length : len} = 'hello';
函数的参数也可以使用解构赋值。例如:
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
上面代码中,函数add
的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x
和y
。对于函数内部的代码来说,它们能感受到的参数就是x
和y
。
在函数的参数中,可以使用解构赋值的形式,并结合默认值的方式,使得函数的参数具备更强的灵活性。
function printPerson({name = 'Unknown', age = 0} = {}) {
console.log(name);
console.log(age);
}
printPerson(); // 使用默认值
printPerson({name: 'Alice', age: 20}); // 传递参数
上面代码中,函数printPerson
的参数是一个对象,通过对这个对象进行解构,得到变量name
和age
的值。如果解构失败,name
和 age
等于默认值。
解构赋值在编写代码时提供了许多便利,可以减少冗余代码,提高代码的可读性和可维护性。
解构赋值可以将一组相互关联的变量赋值,从而避免了重复的变量名。这样可以减少代码量,使得代码更加简洁和易读。
// 传统方式
let firstName = person.firstName;
let lastName = person.lastName;
let age = person.age;
// 使用解构赋值
let {firstName, lastName, age} = person;
解构赋值可以轻松地交换两个变量的值,无需引入第三个变量。
let a = 1;
let b = 2;
// 传统方式
let temp = a;
a = b;
b = temp;
// 使用解构赋值
[a, b] = [b, a];
解构赋值使得函数可以返回多个值,并且可以方便地将函数返回值解构到单个变量中。
function getPerson() {
return {name: 'Alice', age: 20};
}
// 使用解构赋值获取返回值中的属性值
let {name, age} = getPerson();
console.log(name); // Alice
console.log(age); // 20
解构赋值可以方便地从对象或数组中提取参数值,并将其解构到函数的参数中。
function printPerson({name, age}) {
console.log(name);
console.log(age);
}
printPerson({name: 'Alice', age: 20});
解构赋值可以方便地遍历数组或对象,并获取其中的值。
// 遍历数组
let numbers = [1, 2, 3, 4, 5];
for (let [index, value] of numbers.entries()) {
console.log(index, value);
}
// 遍历对象
let person = {name: 'Alice', age: 20};
for (let [key, value] of Object.entries(person)) {
console.log(key, value);
}
解构赋值也可以用于嵌套结构的数据,例如,数组中的元素是对象,或对象中的属性值是数组。在处理嵌套结构时,需要注意解构赋值的层级关系。
let person = {
name: 'Alice',
age: 20,
address: {
city: 'Beijing',
country: 'China'
}
};
// 解构赋值中的嵌套结构
let {name, address: {city, country}} = person;
console.log(name); // Alice
console.log(city); // Beijing
console.log(country); // China
在解构赋值时,数组和对象有一些区别。数组解构赋值是按照位置进行解构,而对象解构赋值是按照属性名进行解构。
// 数组解构赋值按照位置解构
let [a, b, c] = [1, 2, 3];
// 对象解构赋值按照属性名解构
let {name, age} = {name: 'Alice', age: 20};
除了上述基本用法和常见场景外,解构赋值还有一些扩展应用,可以提升代码的灵活性和效率。
使用解构赋值,可以从函数体中返回一个对象,而不是单个的值。这种方式可以方便地返回多个有关联的值,并且可以直接解构到需要的变量中。例如,假设有一个函数getConfig(),它返回一个包含了网站配置信息的对象。我们可以使用解构赋值获取该对象中的属性值:
function getConfig() {
return {
baseURL: 'https://xxxxxx.com',
timeout: 5000
};
}
// 使用解构赋值获取返回对象的属性值
let {baseURL, timeout} = getConfig();
console.log(baseURL); // https://xxxxxx.com
console.log(timeout); // 5000
在上面的例子中,函数getConfig()返回一个包含了baseURL和timeout属性的对象。通过解构赋值,我们可以将对象中的属性直接赋值给相应的变量,使代码更加简洁和直观。
解构赋值也可以方便地从JSON数据中提取所需的值,JSON是一种常见的数据交换格式,在前后端交互中经常使用。例如,假设有一个JSON数据对象jsonData,其中包含了用户的信息。我们可以使用解构赋值从这个对象中提取出需要的值:
let jsonData = {
id: 1,
name: 'Alice',
address: {
city: 'Beijing',
country: 'China'
}
};
// 解构赋值从JSON数据中提取值
let {id, name, address: {city, country}} = jsonData;
console.log(id); // 1
console.log(name); // Alice
console.log(city); // Beijing
console.log(country); // China
在上面的例子中,我们通过解构赋值,从jsonData对象中提取了id、name、address.city和address.country属性的值,并将它们赋给相应的变量。
使用解构赋值,可以方便地处理Promise对象的返回值。Promise是一种处理异步操作的机制,可以使用解构赋值从Promise对象中获取返回值。例如,假设有一个异步函数fetchData(),它返回一个Promise对象,并在异步操作完成后将数据传递给resolve函数。我们可以使用解构赋值获取Promise对象返回值中的特定属性:
function fetchData() {
return new Promise((resolve, reject) => {
// 异步操作的代码...
resolve({data: 'Hello'});
});
}
// 使用解构赋值获取Promise对象的返回值
fetchData().then(({data}) => {
console.log(data); // Hello
});
在上面的例子中,异步函数fetchData返回一个Promise对象,并在异步操作完成后将包含数据的对象传递给resolve函数。通过在解构赋值中使用对象的属性名,我们可以直接获取Promise返回值中的特定属性,这样可以更方便地处理异步操作的结果。
解构赋值是一种从数组或对象中提取值并赋给变量的语法,它可以简化代码,使得对多个变量的赋值更加便捷和直观。在编写代码时,我们可以根据具体的需求选择使用数组解构赋值或对象解构赋值,并结合默认值和剩余参数等特性,来提升代码的可读性和可维护性。同时,了解解构赋值的注意事项和常见问题,以及应用于嵌套结构、函数返回值、函数参数和遍历数据结构等扩展应用,可以更好地发挥解构赋值的潜力。
参考文档:https://blog.csdn.net/dyk11111/article/details/133777237