数组的解构赋值

针对数组,在解构赋值时,使用的是模式匹配,只要等号两边数组的模式相同,右边数组的值就会相应赋给左边数组的变量。通俗讲就是基于数组元素的索引,只要左右两侧的数组元素索引相同就可以。

  1. let [arg1, arg2] = [12, 34];
  2. console.log(num1); // 12
  3. console.log(num2); // 34
  4. // 可以使用逗号作为占位符,只解构需要的值
  5. let [, , num3] = [12, 34, 56];
  6. console.log(num3); // 56
  7. // 右边数组的值不足以将左边数组的值全部赋值时,会解构失败,对应的值就等于“undefined”。
  8. let [num1, num2, num3] = [12, 34];
  9. console.log(num2); // 34
  10. console.log(num3); // undefined

(1)数组解构默认值

在数组解构时设置默认值,可以防止出现解构得到undefined值的情况

  1. let [num1 = 1, num2] = [, 34];
  2. console.log(num1); // 1
  3. console.log(num2); // 34

ES6在判断解构是否会得到undefined值时,使用的是严格等于(===)。只有在严格等于undefined的情况下,才会判断该值解构为undefined,默认值生效的条件是解构值严格等于undefined。

  1. let [
  2. num1 = 1,
  3. num2 = 2,
  4. num3 = 3,
  5. num4 = 4
  6. ] = [null, '', undefined]; //
  7. console.log(num1); // null 因为null并不严格等于undefined,默认值不会生效。
  8. console.log(num2); // '' 空字符串,也不是undefined,默认值也不会生效。
  9. console.log(num3); // 3 值为undefined,默认值生效
  10. console.log(num4); // 4 并没有对应的值,因此会解构为undefined,默认值生效

(2)互换值

数组解构也可以用来进行值的互换,而不需要创建临时变量

  1. // 以前写法
  2. var a = 1;
  3. var b = 2;
  4. var tmp; // 临时变量
  5. tmp = a;
  6. a = b;
  7. b = tmp;
  8. console.log(a); // 2
  9. console.log(b); // 1
  10. // 数组解构赋值
  11. var a = 1;
  12. var b = 2;
  13. // 使用数组的解构赋值交换变量
  14. [b, a] = [a, b];
  15. console.log(a); // 2
  16. console.log(b); // 1

(3)嵌套数组的解构

  1. let [num1, num2, [num3]] = [12, [34, 56], [78, 89]];
  2. console.log(num1); // 12
  3. console.log(num2); // [34, 56]
  4. console.log(num3); // 78

(4)函数参数解构

当函数的参数为数组类型时,可以将实参和形参进行解构

  1. function foo([arg1, arg2]) {
  2. console.log(arg1); // 2
  3. console.log(arg2); // 3
  4. }
  5. foo([2, 3]);

(5) 解析函数返回的数组

函数返回数组,使用数组的解构赋值,可以快速地获取数组元素值。

  1. function fn() {
  2. return [12, 34];
  3. }
  4. let [num1, num2] = fn();
  5. console.log(num1); // 12
  6. console.log(num2); // 34

对象的解构赋值

对象中的属性是没有顺序的,这就要求右侧解构对象的属性名和左侧定义对象的变量名必须相同,这样才可以进行解构。同样,未匹配到的变量名在解构时会赋值“undefined”。

  1. let {m, n, o} = {m: 'kingx', n: 12};
  2. console.log(m); // kingx
  3. console.log(n); // 12
  4. console.log(o); // undefined

事实上,对象解构赋值的原理是:先找到左右两侧相同的属性名(key),然后再赋给对应的变量(value),真正被赋值的是value部分,key并不会被赋值。

  1. let {m: m, n: n} = {m: 'kingx', n: 12};
  2. // 简写方案
  3. let {m, n} = {m: 'kingx', n: 12};
  4. let {m: name, n: age} = {m: 'kingx', n: 12};
  5. console.log(name); // kingx
  6. console.log(age); // 12

(1)对象解构的默认值

对象解构时同样可以设置默认值,默认值生效的条件是对应的属性值严格等于undefined。

  1. let {m, n = 1, a: age = 2, o = true} = {m: 'kingx', o: null};
  2. console.log(m); // kingx
  3. console.log(n); // 1 当属性名和变量名不相同时,用默认值。
  4. console.log(age); // 2 当属性名和变量名不相同时,用默认值。
  5. console.log(o); // null,因为null与undefined不严格相等,默认值并未生效

(2)嵌套对象的解构

嵌套的对象同样可以进行解构,解构时从最外层对象向内部逐层进行,每一层对象值都遵循相同的解构规则。

  1. let obj = {
  2. p: [
  3. 'Hello',
  4. {y: 'World'}
  5. ]
  6. };
  7. let {p: [x, {y: name}]} = obj;
  8. console.log(x); // Hello
  9. console.log(name); // World
  10. console.log(y); // ReferenceError: y is not defined

注意:当父层对象对应的属性不存在,而解构子层对象时,会出错并抛出异常。

  1. let obj = {
  2. m: {
  3. n: 'kingx'
  4. }
  5. };
  6. let {o: {n}} = obj;
  7. console.log(n); // TypeError: Cannot read properties of undefined (reading 'n')

(3)选择性解构对象的属性

假如一个对象有很多通用的函数,那么可以使用解构赋值来获取其中的几个函数。

  1. let { min, max } = Math;
  2. console.log(min(1, 3)); // 1
  3. console.log(max(1, 3)); // 3

(4)函数参数解构

当函数的参数是一个复杂的对象类型时,我们可以通过解构去获得想要获取的值并赋给变量。

  1. function who({displayName: Name, fullName: {firstName: name}}){
  2. console.log(Name + "is" + name);
  3. }
  4. const user = {
  5. id: 42,
  6. displayName: "jdoe",
  7. fullName: {
  8. rstName: "John",
  9. lastName: "Doe"
  10. }
  11. };
  12. who(user); // jdoe is John