【ES6复习】解构赋值

ES6语法糖🍬,通过使用数组或者对象字面量的形式从数组和对象中获取属性并赋值给变量。

这种方式语言清晰简介,并能够很好的处理默认值。

数组的解构赋值

  • 能处理解构数组、类数组对象或者说可遍历的对象( iterable )。
  • 如果解构失败,变量的值就会等于 undefined
  • 解构的默认值需要在成员严等于 undefined 时才会生效。
  • 如果默认值是函数,该函数会在需要默认值时才会执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 传统形式 默认值
let arr = [1, 2, 3];
let a = arr[0];
let b = arr[1];
let c = arr[2];
let d = arr[3] || 4;

// 解构赋值
let [a, b, c] = arr;
// 嵌套操作
let [a, [b], c] = [1, [2], 3];
let [, , c] = [1, 2, 3]; // c=3

// 剩余操作
let [a, ...b] = [1, 2, 3]; // a=1, b=[2,3]

// 解构失败
let [a] = []; // a=undefined

// 默认值 (null !== undefined 所以b未被赋值)
let [a = 4, b = 5, c = 6] = [1, null]; // a=1, b=null, c=6

// 默认值为函数
function foo() {console.log('默认值'); return 100;}
let [a = foo()] = [1]; // a=1 且foo不会被执行

如果解构对象为非可遍历对象,那么将会抛出 TypeError: arr is not iterable的错误。

注意⚠️:非可遍历对象,babel转换时不会报错,但运用时可能会出错。

对象的解构赋值

  • 基本特效和数组相似,但适用于数组和对象。
  • 区别在于数组通过顺序取值,而对象是通过属性名进行取值的。
  • 属性可以重命名。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let { name, age } = { name: "aaa", age: 12 };

// 重命名
let { name:username, age } = { name: "aaa", age: 12 }; // 不会申明name变量

// 嵌套
let person = {
name: {
firsetName: '1',
lastName: '2',
}
};
let { name: {firsetName} } = person; // 同理不会申明name变量

// 对象解构数据
let {'0':foo} = [22]; // foo=22

对已经申明的变量进行解构赋值:

JavaScript 引擎会将 {x} 理解成一个代码块,从而发生语法错误。数组不存在这种问题

1
2
3
4
let x;
{x} = {x: 1}; // 语法错误

({x} = {x: 1}); // 使用括号解决这个问题

用途

  • 变量交换

    1
    2
    let a = 1,b = 2;
    [a, b] = [b, a];
  • 函数参数对应,并设置默认值

    1
    2
    3
    4
    5
    6
    7
    // 数组
    function f([b, b, c, d = 4]) { ... }
    f([1, 2, 3]);

    // 对象
    function f1({a, b, c}) { ... }
    f({a: 1, b: 2, c: 3});
  • 问题1

    1
    2
    3
    4
    5
    6
    // ReferenceError: b is not defined
    let [a = b, b = 1] = [];

    // 等价于
    let a = [0] || b,
    b = [1] || 1;

结合let和const的知识点,由于在使用b时没有申明,所以运行时报错。
如果 [a = 1, b = a]就不会存在这种问题。