美文网首页
ECMAScript(解构)

ECMAScript(解构)

作者: fangPeng__ | 来源:发表于2019-04-18 14:09 被阅读0次

    解构

    数组解构

    • 基本用法
      let [a , b] = [1, 2] // a = 1 b = 2
      let [a, b] = 1 // 报错
      let [a, b] = [1] // a = 1 b = undefined
      let [a, b] = [1, null] // a = 1 b = null
      let [a, ...b] = [1, 2, 3, 4] // a = 1 b = [2, 3, 4]
      let [x, y, z] = new Set(['a', 'b', 'c']) // x = a  y = b  z = c
      
    • 默认值
      let [x = 1, y = x] = [2];    // x=2; y=2
      

    对象解构

    • 基本用法
      let { bar, foo } = { foo: 'aaa', bar: 'bbb' }; // bar = bbb foo = aaa
      let { bar, foo } = { bar: 'bbb' }; // bar = bbb foo = undefined
      // let {bar, foo} 是 let {bar: bar, foo: foo} 的简写 真正赋给值的是:后的
      // 例如
      let { bar: foo } = { bar: 'bbb', foo: 'aaa'} // foo = bbb
      
      // 下面代码中,foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo
      let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
      baz // "aaa"
      foo // error: foo is not defined
      
    • 用于嵌套结构的对象
      let obj = {
        p: [
          'Hello',
          { y: 'World' }
        ]
      };
      
      let { p: [x, { y }] } = obj;
      x // "Hello"
      y // "World"
      
      这时p是模式,不是变量,因此不会被赋值。如果p也要作为变量赋值,可以写成下面这样
      let obj = {
        p: [
          'Hello',
          { y: 'World' }
        ]
      };
      
      let { p, p: [x, { y }] } = obj;
      x // "Hello"
      y // "World"
      p // ["Hello", {y: "World"}]
      
      如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
      // 报错
      let {foo: {bar}} = {baz: 'baz'};
      
    • 对象的解构赋值可以取到继承的属性
        const obj1 = {};
        const obj2 = { foo: 'bar' };
        Object.setPrototypeOf(obj1, obj2);
      
        const { foo } = obj1;
        foo // "bar"
      
      上面代码中,对象obj1的原型对象是obj2。foo属性不是obj1自身的属性,而是继承自obj2的属性,解构赋值可以取到这个属性。
    • 默认值
     let {x, y = 5} = {x: 1};
     x // 1
     y // 5
    
     let {x: y = 3} = {};
     y // 3
    
     let {x: y = 3} = {x: 5};
     y // 5
    

    默认值生效的条件是,对象的属性值严格等于undefined。

    let {x = 3} = {x: undefined};
    x // 3
    
    let {x = 3} = {x: null};
    x // null
    
    • 注意点
      如果要将一个已经声明的变量用于解构赋值

      // 错误的写法
      let x;
      {x} = {x: 1};
      // SyntaxError: syntax error\
      // 因为 JavaScript 引擎会将{x}理解成一个代码块,等号左边是不允许出现代码块语句的,从而发生语法错误
      
      // 正确的写法
      let x;
      ({x} = {x: 1});
      

      由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构

      let arr = [1, 2, 3];
      let {0 : first, [arr.length - 1] : last} = arr;
      first // 1
      last // 3
      

    字符串的解构

    const [a, b, c, d, e] = 'hello';
    a // "h"
    b // "e"
    c // "l"
    d // "l"
    e // "o"
    
    
    let {length : len} = 'hello';
    len // 5
    

    数值和布尔值的解构赋值

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

    let {toString: s} = 123;
    s === Number.prototype.toString // true
    
    let {toString: s} = true;
    s === Boolean.prototype.toString // true
    
    
    
    let { prop: x } = undefined; // TypeError
    let { prop: y } = null; // TypeError
    

    数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。
    解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

    函数参数赋值解构

    [[1, 2], [3, 4]].map(([a, b]) => a + b);
    

    赋值默认值同上

    圆括号问题

    不可使用圆括号

    • 声明语句(函数参数也是声明)
    let ([a]) = [1] 或(let [a] = [1]) // 报错
    
    • 括号包含了模式
    ({a: b}) = {a: 1}
    {(a): b} = {a: 1}
    

    使用圆括号

    {a: (b)} = {a: 1}
    ({a: b} = {a: 1})
    

    相关文章

      网友评论

          本文标题:ECMAScript(解构)

          本文链接:https://www.haomeiwen.com/subject/kgfnwqtx.html