什么是解构赋值?

解构赋值语法是一种 Javascript 表达式。
通过解构赋值,可以将属性/值从对象/数组中取出,赋值给其他变量,称为解构赋值。
参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20


// Stage 4(已完成)提案中的特性
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}

解构数组

  1. 声明变量并赋值时的解构(推荐)
    1
    2
    3
    4
    5
    6
    var foo = ["one", "two", "three"];

    var [one, two, three] = foo;
    console.log(one); // "one"
    console.log(two); // "two"
    console.log(three); // "three"
  2. 先声明变量后在赋值时的解构(推荐第一种)
    1
    2
    3
    4
    5
    var a, b;

    [a, b] = [1, 2];
    console.log(a); // 1
    console.log(b); // 2
  3. 默认值
    为了防止从数组中取出一个值为undefined的对象,可以在表达式左边的数组中为任意对象预设默认值。
    1
    2
    3
    4
    5
    var a, b;

    [a=5, b=7] = [1];
    console.log(a); // 1
    console.log(b); // 7
  4. 交换变量
    在一个解构表达式中可以交换两个变量的值
    1
    2
    3
    4
    5
    6
    var a = 1;
    var b = 3;

    [a, b] = [b, a];
    console.log(a); // 3
    console.log(b); // 1
  5. 函数返回值
    1
    2
    3
    4
    5
    6
    7
    8
    function fn() {
    return [1, 2];
    }

    var a, b;
    [a, b] = fn();
    console.log(a); // 1
    console.log(b); // 2
  6. 忽略某些返回值
    1
    2
    3
    4
    5
    6
    7
    function fn() {
    return [1, 2, 3];
    }

    var [a, , b] = fn();
    console.log(a); // 1
    console.log(b); // 3
  7. 将剩余数组赋值给一个变量
    1
    2
    3
    var [a, ...b] = [1, 2, 3];
    console.log(a); // 1
    console.log(b); // [2, 3]

解构对象

  1. 常见赋值
    1
    2
    3
    4
    5
    var o = {aa: 42, bb: true};
    var {aa, bb} = o;

    console.log(aa); // 42
    console.log(bb); // true
  2. 无声明赋值
    1
    2
    3
    ({a, b} = {a: 1, b: 2});
    console.log(a)
    console.log(b)
  3. 给新的变量名赋值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var o = {aa: 42, bb: true};
    var {aa: foo, bb: bar} = o;

    console.log(foo); // 42
    console.log(bar); // true

    // 给新的变量命名并提供默认值
    var {a:aa = 10, b:bb = 5} = {a: 3};

    console.log(aa); // 3
    console.log(bb); // 5
  4. 默认值
    1
    2
    3
    4
    var {a = 10, b = 5} = {a: 3};

    console.log(a); // 3
    console.log(b); // 5
  5. 解构嵌套对象和数组
    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
    const post_info = {
    title: "Lete乐特's Blog",
    post: [
    {
    locale: 'zh-cn',
    localization_tags: [],
    last_edit: '2021-07-11 21:54:27',
    url: 'https://blog.lete114.top/article/Destructuring-assignment.html',
    title: 'JavaScript解构赋值'
    }
    ],
    url: '/article/Destructuring-assignment.html'
    };

    let {
    title: site_title, // 重命名
    post: [
    {
    title: post_title, // 重命名
    },
    ],
    } = post_info;

    console.log(site_title); // Lete乐特's Blog
    console.log(post_title); // JavaScript解构赋值
  6. 将剩余数组赋值给一个变量
    1
    2
    3
    4
    let {a, b, ...remain} = {a: 10, b: 20, c: 30, d: 40}
    console.log(a); // 10
    console.log(b); // 20
    console.log(remain); // { c: 30, d: 40 }
  7. 处理无效的对象key
    1
    2
    3
    4
    let foo = { 'user-name': 'Lete' };
    let { 'user-name': UserName } = foo;
    // UserName是自定义的
    console.log(UserName); // "Lete"
  8. 解构对象时会查找原型链(如果属性不在对象自身,将从原型链中查找)
    1
    2
    3
    4
    5
    6
    7
    8
    // 声明对象 和 自身 self 属性
    var obj = {self: '123'};
    // 在原型链中定义一个属性 prot
    obj.__proto__.prot = '456';
    // test
    const {self, prot} = obj;
    console.log(self);// self "123"
    console.log(prot);// prot "456"(访问到了原型链)