第 3 章 变量的解构赋值

变量的解构赋值

1. 数组的解构赋值

基本用法

  • ES6 允许按照一定的模式从数组和对象中提取值,然后对变量进行赋值,这被称为解构

    1
    let [a, b, c] = [1, 2, 3];
  • 只要等号两边的模式相同,左边的变量就会被赋予对应的值

  • 可以使用嵌套数组进行解构
  • 如果解构不成功,变量的值就会等于 undefined
  • 如果等号的右边不是可遍历的结构,就会报错
  • 只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值

默认值

  • 解构赋值允许指定默认值

    1
    let [foo = true] = [];
  • ES6 内部使用严格相等运算符(===)判断一个位置是否有值。所以如果一个数组成员不严格等于 undefined,默认值是不会生效的

  • 如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到时才会求值
  • 默认值可以引用解构赋值的其他变量,但该变量必须已经声明

2. 对象的解构赋值

  • 数组的元素是按次序排列的,变量的取值是由它的位置决定的;而对象的属性没有次序,变量必须与属性同名才能取到正确的值

    1
    let {foo, bar} = {foo: "aaa", bar: "bbb"};
  • 对象的解构赋值是下面形式的简写

    1
    let {foo: foo, bar: bar};
  • 对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是后者,而不是前者

    1
    2
    3
    let {foo: baz} = {foo: "aaa", bar: "bbb"};
    baz // "aaa"
    foo // error: foo is not defined
  • 上面代码中,foo 是匹配的模式,baz 才是变量。真正被赋值的是变量 baz,而不是模式 foo

  • 与数组一样,解构也可以用于嵌套结构的对象
  • 对象的解构也可以指定默认值
  • 默认值生效的条件是,对象的属性值严格等于 undefined
  • 如果解构失败,变量的值等于 undefined
  • 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构

3. 字符串的解构赋值

  • 字符串也可以解构赋值,因为此时字符串被转换成一个类似数组的对象
  • 类似数组的对象都有一个 length 属性,因此还可以对这个属性进行解构赋值

4. 数值和布尔值的解构赋值

  • 解构赋值时,如果等号后边是数值和布尔值,则会先转化为对象
  • 解构赋值的规则是,如果等号后边的值不是对象或数组,就会先将其转化为对象。由于 undefined 和 null 无法转化为对象,所以对它们进行解构赋值时都会报错

5. 函数参数的解构赋值

  • 函数参数可以使用解构赋值
  • 函数参数的解构也可以使用默认值

6. 圆括号问题

ES6 的规则是,只要有可能导致解构的歧义,就不得使用圆括号

不能使用圆括号的情况

  • 变量声明语句

    1
    2
    // 报错
    let [(a)] = [1];
  • 函数参数

    函数参数也属于变量声明,因此不能使用圆括号

    1
    2
    // 报错
    function f([(z)]){return z;}
  • 赋值语句的模式

    1
    2
    // 报错
    ([a]) = [5]

可以使用圆括号的情况

  • 可以使用圆括号的情况只有一种:赋值语句的非模式部分可以使用圆括号

7. 用途

  • 交换变量的值

    1
    2
    3
    4
    let x = 1;
    let y = 2;

    [x, y] = [y, x];
  • 从函数返回多个值

    解构赋值方便取出这些值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 返回一个数组
    function example(){
    return [1, 2, 3];
    }
    let [a, b, c] = example();

    // 返回一个对象
    function example(){
    return {
    foo: 1,
    bar: 2
    };
    }
    let {foo, bar} = example();
  • 函数参数的定义

    解构赋值方便将一组参数与变量名对应起来

    1
    2
    3
    4
    5
    6
    7
    // 参数是一组有次序的值
    function f([x, y, z]){...}
    f([1, 2, 3]);

    // 参数是一组无次序的值
    function f({x, y, z}){...}
    f({z: 3, y: 2, x: 1});
  • 提取 JSON 数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    let jsonData = {
    id: 42,
    status: "OK",
    data: [867, 5309]
    };

    let {id, status, data: number} = jsonData;

    console.log(id. status, number);
    // 42, "OK", [867, 5309]
    - 函数参数的默认值
    - 遍历 Map 结构
    > 任何部署了 Iterator 接口的对象都可以用 for...of 循环遍历
    - 输入模块的指定方法
    ```js
    const {SourceMapConsumer, SourceNode} = require("source-map");
-------------本文结束 感谢您的阅读-------------
您的支持将鼓励我继续创作!