数组的解构赋值
针对数组,在解构赋值时,使用的是模式匹配,只要等号两边数组的模式相同,右边数组的值就会相应赋给左边数组的变量。通俗讲就是基于数组元素的索引,只要左右两侧的数组元素索引相同就可以。
let [arg1, arg2] = [12, 34];
console.log(num1); // 12
console.log(num2); // 34
// 可以使用逗号作为占位符,只解构需要的值
let [, , num3] = [12, 34, 56];
console.log(num3); // 56
// 右边数组的值不足以将左边数组的值全部赋值时,会解构失败,对应的值就等于“undefined”。
let [num1, num2, num3] = [12, 34];
console.log(num2); // 34
console.log(num3); // undefined
(1)数组解构默认值
在数组解构时设置默认值,可以防止出现解构得到undefined值的情况
let [num1 = 1, num2] = [, 34];
console.log(num1); // 1
console.log(num2); // 34
ES6在判断解构是否会得到undefined值时,使用的是严格等于(===)。只有在严格等于undefined的情况下,才会判断该值解构为undefined,默认值生效的条件是解构值严格等于undefined。
let [
num1 = 1,
num2 = 2,
num3 = 3,
num4 = 4
] = [null, '', undefined]; //
console.log(num1); // null 因为null并不严格等于undefined,默认值不会生效。
console.log(num2); // '' 空字符串,也不是undefined,默认值也不会生效。
console.log(num3); // 3 值为undefined,默认值生效
console.log(num4); // 4 并没有对应的值,因此会解构为undefined,默认值生效
(2)互换值
数组解构也可以用来进行值的互换,而不需要创建临时变量
// 以前写法
var a = 1;
var b = 2;
var tmp; // 临时变量
tmp = a;
a = b;
b = tmp;
console.log(a); // 2
console.log(b); // 1
// 数组解构赋值
var a = 1;
var b = 2;
// 使用数组的解构赋值交换变量
[b, a] = [a, b];
console.log(a); // 2
console.log(b); // 1
(3)嵌套数组的解构
let [num1, num2, [num3]] = [12, [34, 56], [78, 89]];
console.log(num1); // 12
console.log(num2); // [34, 56]
console.log(num3); // 78
(4)函数参数解构
当函数的参数为数组类型时,可以将实参和形参进行解构
function foo([arg1, arg2]) {
console.log(arg1); // 2
console.log(arg2); // 3
}
foo([2, 3]);
(5) 解析函数返回的数组
函数返回数组,使用数组的解构赋值,可以快速地获取数组元素值。
function fn() {
return [12, 34];
}
let [num1, num2] = fn();
console.log(num1); // 12
console.log(num2); // 34
对象的解构赋值
对象中的属性是没有顺序的,这就要求右侧解构对象的属性名和左侧定义对象的变量名必须相同,这样才可以进行解构。同样,未匹配到的变量名在解构时会赋值“undefined”。
let {m, n, o} = {m: 'kingx', n: 12};
console.log(m); // kingx
console.log(n); // 12
console.log(o); // undefined
事实上,对象解构赋值的原理是:先找到左右两侧相同的属性名(key),然后再赋给对应的变量(value),真正被赋值的是value部分,key并不会被赋值。
let {m: m, n: n} = {m: 'kingx', n: 12};
// 简写方案
let {m, n} = {m: 'kingx', n: 12};
let {m: name, n: age} = {m: 'kingx', n: 12};
console.log(name); // kingx
console.log(age); // 12
(1)对象解构的默认值
对象解构时同样可以设置默认值,默认值生效的条件是对应的属性值严格等于undefined。
let {m, n = 1, a: age = 2, o = true} = {m: 'kingx', o: null};
console.log(m); // kingx
console.log(n); // 1 当属性名和变量名不相同时,用默认值。
console.log(age); // 2 当属性名和变量名不相同时,用默认值。
console.log(o); // null,因为null与undefined不严格相等,默认值并未生效
(2)嵌套对象的解构
嵌套的对象同样可以进行解构,解构时从最外层对象向内部逐层进行,每一层对象值都遵循相同的解构规则。
let obj = {
p: [
'Hello',
{y: 'World'}
]
};
let {p: [x, {y: name}]} = obj;
console.log(x); // Hello
console.log(name); // World
console.log(y); // ReferenceError: y is not defined
注意:当父层对象对应的属性不存在,而解构子层对象时,会出错并抛出异常。
let obj = {
m: {
n: 'kingx'
}
};
let {o: {n}} = obj;
console.log(n); // TypeError: Cannot read properties of undefined (reading 'n')
(3)选择性解构对象的属性
假如一个对象有很多通用的函数,那么可以使用解构赋值来获取其中的几个函数。
let { min, max } = Math;
console.log(min(1, 3)); // 1
console.log(max(1, 3)); // 3
(4)函数参数解构
当函数的参数是一个复杂的对象类型时,我们可以通过解构去获得想要获取的值并赋给变量。
function who({displayName: Name, fullName: {firstName: name}}){
console.log(Name + "is" + name);
}
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
who(user); // jdoe is John