解构赋值

ECMAScript 6允许按照一定模式从数组或对象中提取值,对变量进行赋值。这种赋值方式被称为解构赋值。

ECMAScript 6的“解构赋值”本质上属于“模式匹配”。赋值运算符两边的模式相同,左边的变量会被赋予对应位置的值。

变量的解构赋值

从指定的数组或对象中提取值,为指定变量进行赋值。

1
var/let [变量名1,变量名2,变量名3] = 数组或对象

变量的索引值对应值的索引值。

1
2
3
let [a, b, c] = [1, 2, 3];

console.log(a, b, c); // 1 2 3

赋值失败

1
2
3
let [a] = [];

console.log(a); // undefined

以上代码相当于定义了一个变量a,但未初始化(赋值)

1
2
let [n, m] = [1];
console.log(n, m); // 1 undefined

以上代码表示由于变量只有一个,而定义变量有两个,因此m不会得到值。

不完全解构赋值

即定义变量的数量小于值的数量。

1
2
let [a, b] = [1, 2, 3];
console.log(a, b); // 1,2

默认值

只有当解耦失败时才会使用默认值。例如:

1
2
3
4
let [a = 1] = [];
console.log(a); // 1
let [b = 1] = [100];
console.log(b); // 100

但有两种特殊情况需要注意。

  1. 如果含有默认值,而恰好被赋值为undefiend

    1
    2
    3
    // 底层将为变量赋值的值与undefined进行比较
    let [x, y = 100] = [100, undefined];
    console.log(x, y); // 100 100

    变量如果有默认值则不会被赋值为undefined

  2. 如果含有默认值,而恰好被赋值为null

    1
    2
    3
    // 只与undefined比较
    let [v, w = 100] = [100, null];
    console.log(v, w); // 100 null

    变量如果有默认值则会被赋值为null

对象的解构赋值

1
2
3
4
5
6
7
// 变量名与属性名要一一对应
let { x, y } = {
x: 10,
y: 20,
};

console.log(x, y); // 10 20
  1. 变量名与属性名一一对应

  2. 左右两边的类型要相同

  3. 结构又要保持一致

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    let {
    m: { age, name },
    n,
    } = {
    m: {
    age: 12,
    name: "123",
    },
    n: 10,
    };
    console.log(n, age, name); // 10 12 123
    console.log(m); // 报错 m is not defined
  4. 对象解构赋值的情况与变量的解构赋值大致相同。也存在解耦失败,不完全解耦,默认值等情况。

字符串、数字值、和布尔值的解构赋值

字符串的解构赋值

1
2
3
4
5
let [a, b, c, d, e, f, g, h] = "xiaokang";
console.log(a, b, c, d, e, f, g, h); //x i a o k a n g

let [v, m, n] = "大前端";
console.log(v, m, n); // 大 前 端

变量的数量与字符串中字符的数量对应。

数字值的解构赋值

1
let { toString: m } = 100;

image-20201025153751948

布尔值的解构赋值

1
let { toString: m } = true;

函数的参数解构赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 数组解耦
function fn1([n, m]) {
console.log(n, m);
}
fn1([10, 20]); //10 20

// 对象解耦
function fn2({ n, m }) {
console.log(n, m);
}
fn2({
n: 10,
m: 20,
}); //10 20

  • 函数定义时相当于在函数作用域中定义了一个局部变量(没有赋值)
  • 实参,相当于在函数作用域中为定义的变量的变量进行赋值

解构赋值的用途

  1. 交换变量的值。

    1
    2
    3
    4
    5
    6
    7
    // 1. 交换变量的值
    let x = 1;
    let y = 2;

    console.log(x, y); // 1 2
    [x, y] = [y, x];
    console.log(x, y); // 2 1
  2. 返回多个值

    1
    2
    3
    4
    5
    function fn() {
    return { a: 1, b: 2, c: 3 };
    }
    let { a, b, c } = fn();
    console.log(a, b, c); //1 2 3
  3. 函数参数的定义

    1
    2
    3
    4
    function f([a, b, c = 3]) {
    console.log(a, b, c);
    }
    f([1, 2]); //1 2 3
  4. 提取json格式的数据

    1
    2
    3
    4
    5
    6
    let jsonData = {
    name: "xiaokang",
    age: 20,
    };
    let { name, age } = jsonData;
    console.log(name, age); // xiaokang 20