JavaScript 的解构赋值是一种从数组 or 对象中提取值并将其赋给变量的语法。这种语法让我们从复杂的数据结构中提取数据变得简洁和易读。解构赋值可以用在数组、对象以及嵌套结构中。
解构是:使用 ES6 的一种语法规则,将一个对象或数组的某个属性提取到某个变量中。
解构不会对被解构的目标造成任何影响。
1. 数组解构赋值
数组解构赋值允许我们将数组中的值提取到变量中。基本语法如下:
const [a, b, c] = [1, 2, 3];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
如果数组的某个位置没有值,可以为其设置默认值:
const [x = 1, y = 2] = [10];
console.log(x); // 10
console.log(y); // 2
使用 ... 运算符可以将剩余的元素放入一个数组中:
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [2, 3, 4, 5]
2. 对象解构赋值
对象解构赋值允许我们将对象的属性值提取到变量中。基本语法如下:
const { name, age } = { name: 'Alice', age: 18 };
console.log(name); // 'Alice'
console.log(age); // 18
如果对象中没有指定的属性,可以为其设置默认值:
const { name, age = 30 } = { name: 'Bob' };
console.log(name); // 'Bob'
console.log(age); // 30
可以给解构出来的属性重新命名:
const { name: fullName, age: years } = { name: 'Charlie', age: 35 };
console.log(fullName); // 'Charlie'
console.log(years); // 35
可以解构嵌套的对象:
const person = {name: 'Dave',address: {city: 'New York',zip: '10001'}
};const { name, address: { city, zip } } = person;
console.log(name); // 'Dave'
console.log(city); // 'New York'
console.log(zip); // '10001'
在嵌套解构中设置默认值:
const person = {name: 'Eve',address: {}
};const { name, address: { city = 'Unknown' } } = person;
console.log(name); // 'Eve'
console.log(city); // 'Unknown'
3. 解构赋值在函数参数中的应用
解构赋值可以直接在函数参数中使用,简化函数调用:
function greet({ name, age }) {console.log(`Hello ${name}, you are ${age} years old.`);
}const user = { name: 'Frank', age: 4 };
greet(user); // Hello Frank, you are 4 years old.
4. 解构赋值与变量交换
可以利用解构赋值来交换变量的值:
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
5. 注意点
5.1 默认值的计算
当使用默认值时,这些默认值是在解构赋值操作时计算的:
const { x = Math.random() } = {};
console.log(x); // 每次运行都可能是不同的值
如果对象中的属性已经有值,则默认值不会被使用,只在目标属性为 undefined 时使用。
const { x = Math.random() } = {x: 10};
console.log(x); // 10
5.2 解构赋值中的 undefined 和 null
解构赋值仅对 undefined 提供默认值,不对 null 提供。如果对象的属性是 null,默认值不生效。
const { a = 1 } = { a: null };
console.log(a); // null
5.3 解构赋值的深度
深度解构需要确保每一层的对象结构都存在。否则会引发错误:
const obj = { a: { b: 1 } };
const { a: { b, c = 2 } } = obj;
console.log(b); // 1
console.log(c); // 2// 如果 obj = {},则会抛出错误
// const { a: { b, c = 2 } } = {};
5.4 解构赋值的计算顺序
在对象解构赋值中,计算顺序可能会影响结果:
const obj = { a: 1 };
const { a, b = a } = obj;
console.log(a); // 1
console.log(b); // 1
此处,a 赋值为 1,b 的默认值是 a,因此 b 的值是 1。
const obj = { a: 1, b: 2 };
const { a = 10, b = a } = obj;
console.log(a); // 1
console.log(b); // 2
此处,a 和 b 各自存在值,均不使用默认值。
5.5 解构赋值与函数参数
在函数参数中使用解构赋值时,要确保传入的参数结构与解构的变量名一致:
function func({ a, b }) {console.log(a, b);
}
func({ a: 1, b: 2 }); // 1 2
func({ a: 1 }); // 1 undefined
func({}); // undefined undefined
5.6 解构赋值与函数默认参数
在函数的参数解构中使用默认值时,需要注意函数参数的默认值的顺序:
function func({ a = 1, b = a } = {}) {console.log(a, b);
}
func(); // 1 1
func({ a: 2 }); // 2 2
func({ b: 3 }); // 1 3
5.7 防止解构赋值错误
确保在解构赋值之前检查对象或数组是否存在。如果对象或数组是 null 或 undefined,尝试解构将会引发错误:
let obj = null;
// const { a } = obj; // 这会抛出错误obj = {};
const { a = 1 } = obj;
console.log(a); // 1
5.8 解构赋值中的计算属性名
如果需要解构具有动态计算属性名的对象,确保正确地使用方括号语法:
const key = 'b';
const obj = { a: 1, [key]: 2 };const { [key]: value } = obj;
console.log(value); // 2