解构赋值 —— ES6基础总结(三)

975 阅读3分钟

概念

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

认识:

    let [a, b] = [1, 2]
    a   // 1
    b   // 2

图解:

解构赋值

条件:

  1. 等号两边结构一致;

    let [{a, b}, c] = {a: 1, b: 2, c: 3}    // Uncaught TypeError: {(intermediate value)(intermediate value)(intermediate value)} is not iterable
    
  2. 定义与赋值同时完成。

    let [a, b]
    [a, b] = [1, 2]     // Uncaught SyntaxError: Missing initializer in destructuring declaration
    

下面我们将分别介绍数组、对象、函数参数、字符串、数值和布尔值的解构赋值。

数组

  1. 嵌套使用;

    let [a, [[b], c]] = [1, [[2], 3]]
    a   // 1
    b   // 2
    c   // 3
    
  2. 解构失败,输出undefined;

    let [a, b, c] = [1, 2]
    a   // 1
    b   // 2
    c   // undefined
    
  3. 不完全解构;

    let [a, b] = [1, 2, 3]
    a   // 1
    b   // 2
    
  4. 需具备Iterator接口;

    let [a] = 'hello'
    a   // "h"
    
    let [a, b] = new Set([1, 2]);
    a   // 1
    b   // 2
    
    let [a] = true  // Uncaught ReferenceError: a is not defined
    
  5. 默认值。

    只有当一个数组成员严格等于undefined,默认值才会生效。

    let [a = 1, b = 2, c = 3] = [undefined, null, false] 
    a   // 1
    b   // null
    c   // false
    

    如果默认值是一个表达式,那么这个表达式是惰性求值的。

    function f() {
      console.log('test')
    }
    
    let [a = f()] = [1]
    a   // 1
    

    默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

    let [a = 1, b = a] = [];
    a   // 1
    b   // 1
    
    let [a = 1, b = a] = [2]
    a   // 2
    b   // 2
    

对象

  1. 变量必须与属性同名,才能取到正确的值,且无需关注次序;

    let {a, b, c} = {b: 2, a: 1, cc: 3}
    a   // 1
    b   // 2
    c   // undefined
    
  2. 嵌套使用;

    let obj = {
      p: [
        'Hello',
        { b: 'World' }
      ]
    }
    
    let { p: [a, { b }] } = obj     // 这时p是模式,不是变量,因此不会被赋值。
    a   // Hello
    b   // World
    

    如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。

    let {a: {a1}, b: {b1}} = {a: {a1: 1}}   // Uncaught TypeError: Cannot destructure property `b1` of 'undefined' or 'null'
    

    对象的解构赋值可以取到继承的属性。

    let obj1 = {}
    let obj2 = { a: 1 }
    Object.setPrototypeOf(obj1, obj2)
    
    let { a } = obj1
    a   // 1
    
  3. 解构失败,输出undefined,同数组;

    let {a, b} = {a: 1}
    a   // 1
    b   // undefined
    
  4. 不完全解构,同数组;

    let {a} = {a: 1, b: 2}
    a   // 1
    
  5. 变量名与属性名不一致;

    let { a: test } = { a: 1 }
    test    // 1
    
  6. 默认值,同数组。

函数参数

    [[1, 2], [3, 4]].map(([a, b]) => a + b)     // [3, 7]
    [[1, 2], [3, 4]].map(([a, b, c = 100]) => a + b + c)    // [103, 107]

字符串

字符串被转换成了一个类似数组的对象。

    let [a, b] = 'hello'
    a   // "h"
    b   // "e"
    
    let {length : l} = 'hello'
    l   // 5

数值 & 布尔值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

    let {toString: s} = 123;
    s === Number.prototype.toString // true
    
    let {toString: s} = true;
    s === Boolean.prototype.toString // true

用途

  1. 交换值;

    let a = 1
    let b = 2
    
    [a, b] = [b, a]
    a   // 2
    b   // 1
    
  2. 函数返回多个值;

    function test () {
        return [1, 2]
    }
    
    let [a, b] = test()
    a   // 1
    b   // 2
    
  3. 函数参数的定义;

    function test ([a, b]) {
        return a + b
    }
    
    test([1, 2])    // 3
    
  4. 提取JSON数据;

    let json = {
        a: 1,
        b: 2
    }
    
    let {a, b} = json
    a   // 1
    b   // 2
    
  5. 函数参数的默认值;

    function test (obj = {a: 1, b: 2}) {
        return obj.a + obj.b
    }
    test()  // 3
    test({a: 100, b: 100})  // 200
    
  6. 遍历Map结构;

    let map = new Map([
        ['a', 1],
        ['b', 2]
    ])
    
    for (let [key, value] of map) {
        console.log(`${key} : ${value}`)    // a : 1 b : 2
    }
    
  7. 输入模块的指定方法。

    import {Text, View} from "react-native"
    

参考

ECMAScript 6 入门

小结

本文主要介绍了数组、对象、函数参数、字符串、数值和布尔值的解构赋值,其中,数组和对象在日常开发中使用超级频繁,掌握好二者的解构赋值会大大减少容错代码,提高开发效率。函数参数就是使用解构赋值的好地方。

需特别注意:

  1. 数组解构赋值需具备Iterator接口;
  2. 对象解构赋值需特别注意变量名与属性名;
  3. 解构失败,输出undefined;
  4. 默认值在===undefined时才会生效。

感谢阅读,如有问题,欢迎指正。

最后祝大家五四青年节快乐,吃好喝好玩好!