zoukankan      html  css  js  c++  java
  • 解构赋值

    1.数组的解构赋值

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

    1.本质上,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

    2.如果解构不成功,变量的值就等于undefined。

    3.如果等号右边不是数组(或者不是可遍历的结构),将会报错。

    例子:

    let [foo, [[bar], baz]] = [1, [[2], 3]];
    //foo:1,bar:2, baz:3
    let [ , , third] = ["foo", "bar", "baz"];
    //third:baz
    let [x, , y] = [1, 2, 3];
    //x:1, y:3
    let [head, ...tail] = [1, 2, 3, 4];
    //head:1, tail:[2,3,4]
    let [x, y, ...z] = ['a'];
    //x:a, y:undefined, z:[]
    
    //报错
    let [foo] = 1;
    let [foo] = false;
    let [foo] = NaN;
    let [foo] = undefined;
    let [foo] = null;
    let [foo] = {};

    不完全解构:即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

    例:

    let [x, y] = [1, 2, 3];
    //x:1, y:2
    let [a, [b], d] = [1, [2, 3], 4];
    //a:1, b:2, d:4

    默认值:解构赋值允许指定默认值。

    注意:

    1.ES6内部使用严格相等运算符(===)来判断一个位置是否有值,所以,只有当一个数组成员严格等于undefined,默认值才会生效。

    2.如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

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

    例:

    let [foo = true] = [];
    //foo:true
    let [x, y = 'b'] = ['a'];
    //x:a, y:b
    let [x, y = 'b'] = ['a', undefined]; 
    //x:a, y:b
    let [x = 1] = [undefined];
    //x:1
    let [x = 1] = [null];
    //x:null
    
    //引用其他变量
    let [x = 1, y = x] = [];
    //x:1, y:1
    let [x = 1, y = x] = [2]; 
    //x:2, y:2
    let [x = 1, y = x] = [1, 2]; 
    //x:1, y:2
    let [x = y, y = 1] = [];
    //报错

    2.对象的解构赋值

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

    let { bar, foo } = { foo: "aaa", bar: "bbb" };
    //bar:bbb, foo:aaa
    let { baz } = { foo: "aaa", bar: "bbb" };
    //baz:undefined

    如果变量名与属性名不一致,必须写成下面这样

    let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
    //baz:aaa
    let obj = { first: 'hello', last: 'world' };
    let { first: f, last: l } = obj;
    //first是匹配的模式,f才是变量。真正被赋值的是变量f,而不是模式first。 f:hello, l:world

    解构嵌套结构的对象

    let obj = {
      p: [
        'Hello',
        { y: 'World' }
      ]
    };
    
    let { p: [x, { y }] } = obj;
    //x:Hello, y:World
    
    let obj = {
      p: [
        'Hello',
        { y: 'World' }
      ]
    };
    
    let { p, p: [x, { y }] } = obj;
    //p:['Hello',{y: 'World' }],  x:Hello, y:World
    
    const node = {
      loc: {
        start: {
          line: 1,
          column: 5
        }
      }
    };
    
    let { loc, loc: { start }, loc: { start: { line }} } = node;
    //line:1,
    //start: { line: 1, column: 5}
    //loc:{start: { line: 1, column: 5} }
    //注意:在最后一次对line属性的解构赋值之中,只有line是变量
    
    let obj = {};
    let arr = [];
    ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
    //obj:{prop:123}, arr:[true]

    默认值(同数组):

    如果解构模式是嵌套的对象,而且子对象所在的父元素不存在,将会报错

    var {x = 3} = {};
    //x:3
    var {x, y = 5} = {x: 1};
    //x:1, y:5
    var {x: y = 3} = {};
    //y:3
    var {x: y = 3} = {x: 5};
    //y:5
    var {x = 3} = {x: undefined};
    //x:3
    var {x = 3} = {x: null};
    //x:null
    let {foo} = {bar: 'baz'};
    //foo:undefined
    let {foo: {bar}} = {baz: 'baz'};
    //报错

    如果要将一个已经声明的变量用于解构赋值,外面要加一个圆括号。

    let x;
    {x} = {x: 1};
    //报错,JavaScript会将{x}理解成一个代码块,从而发生语法错误
    
    let x;
    ({x} = {x: 1});

    3.字符串的解构赋值

    字符串解构赋值时,字符串被转换成一个类似数组的对象。

    还可以对length属性进行解构赋值。

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

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

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

    如果是undefined和null无法转为对象,在对他们进行解构赋值会报错。

    let { prop: x } = undefined; // TypeError
    let { prop: y } = null; // TypeError

    5.函数参数的解构赋值

    function move({x = 0, y = 0} = {}) {
      return [x, y];
    }
    
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, 0]
    move({}); // [0, 0]
    move(); // [0, 0]
    
    function move({x, y} = { x: 0, y: 0 }) {
      return [x, y];
    }
    
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, undefined]
    move({}); // [undefined, undefined]
    move(); // [0, 0]

    参考:《es6标准入门》

     

  • 相关阅读:
    71. Simplify Path
    68. Text Justification
    65. Valid Number
    64. Minimum Path Sum
    More Effective C++ 条款12 了解”抛出一个exception"与“传递一个参数”或“调用一个虚函数”之间的差异
    More Effective C++ 条款11 禁止异常流出destructor之外
    More Effective C++ 条款10 在构造函数内阻止内存泄露
    More Effective C++ 条款9 利用 destructor 避免泄露资源
    More Effective C++ 条款7 千万不要重载&&,||和,操作符
    More Effective C++ 条款6 区别 increment/decrement 操作符的前置(prefix)和后置(postfix)形式
  • 原文地址:https://www.cnblogs.com/zsj-02-14/p/10209192.html
Copyright © 2011-2022 走看看