欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

对象的解构赋值

程序员文章站 2022-03-04 23:45:35
...

解构不仅可以用于数组,还可以用于对象,直接来看个简单粗暴的

    let { first, second } = { first: 1, second: 2 };
    console.log(first, second); //1 2

与数组解构不同的是,数组的元素是按次序排列的,变量取值是由它的位置(下标)决定。在对象的属性中没有次序,变量与属性同名,才能取到正确的值

    //等号左边两个变量的次序跟右边不一致,对取值完全没影响
    let { second, first } = { first: 1, second: 2 };
    console.log(first, second); //1 2

    //等号左边的变量没有对应的同名属性,所以取不到值,遂等于undefined
    let { thrid } = { first: 1, second: 2 };
    console.log(thrid); // undefined

如果变量名与属性名不一样,需要写成下面这样????

    let { foo: first } = { foo: 'AAA', bar: 'BBB' };
    console.log(first); // AAA

    let obj = { first: 'AAA', second: 'BBB' };
    let { first: a, second: b } = obj;
    console.log(a, b); // AAA BBB
    
    //上两例说明,对象的解构赋值其实就是下面形式的简写
    let { first: first, second: second } = { first: 1, second: 2 };
    console.log(first, second); //1 2

对象的解构赋值机制是先找到同名属性,再赋值给对应的变量。真正被赋值的是后者,而不是前者

    //first是匹配的模式,second才是变量,被赋值的是变量second,
    let { first: second } = { first: 'FIRST', second: 'SECOND' };
    console.log(first); //报错:first is not defined
    console.log(second); // FIRST

解构也可以用于嵌套解构的对象

    let obj = {
        first: [
            'AAA',
            {
                second: 'BBB'
            }
        ]
    }
    let { first: [a, { second }] } = obj;
    //此时,first为匹配模式,相当于[a, { second }] = ['AAA',{second: 'BBB'}]
    //先是数组的解构赋值,然后是对象的解构赋值
    console.log(a, second);// AAA BBB

此时,first是模式,不是变量,不会被赋值,如果first也要作为变量赋值的话,可以写成这样????

    let obj = {
        first: [
            'AAA',
            {
                second: 'BBB'
            }
        ]
    }
    let { first, first: [a, { second }] } = obj;
    //相当于 let { first: first, first: [a, { second }] } = obj;
    console.log(a, second); // AAA BBB
    console.log(first); // ["AAA", {second: "BBB"}]

再举个????

    const obj = {
        loc: {
            start: {
                line: 1,
                column: 2
            }
        }
    }
    let { loc, loc: { start }, loc: { start: { line } } } = obj;
    //相当于这样:let { loc: loc, loc: { start: start }, loc: { start: { line: line } } } = obj;
    //分别有三次解构赋值,分别是对loc,start,line三个属性的解构赋值
    //在最后一次对line属性解构赋值中,只有line是变量,loc和start都是模式
    console.log(loc); // {start: {line: 1, column: 2}}
    console.log(start); // {line: 1, column: 2}
    console.log(line); // 1

再来个嵌套赋值的????

    let obj = {};
    let arr = [];
    ({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true })
    //此时,foo和bar是匹配模式,被赋值的是 obj和 arr
    console.log(obj); // {prop: 123}
    console.log(arr); // [true]

为什么上面的代码中({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true })用括号包起来,是因为JavaScript引擎会将 { foo: obj.prop, bar: arr[0] }理解为一个代码块,从而发生语法错误。

  • 错误写法

      let x; 
      { x } = { x: 1 }; //报错
    
  • 正确写法

      let x;
      ({ x } = { x: 1 });
      console.log(x); // 1
    

对象的解构也可以指定默认值

    let { a = 3 } = {};
    console.log(a); // 3

    let { b, c = 3 } = { b: 1 };
    console.log(b); // 1
    console.log(c); // 3

    let { x: y = 3 } = {};
    console.log(y); // 3

    let { j: i = 3 } = { j: 1 };
    console.log(i); // 1

    let { message: msg = 'Hello Mr Wang' } = {};
    console.log(msg); // Hello Mr Wang

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

    let { x = 1 } = { x: undefined };
    console.log(x); // 1

    let { x = 1 } = { x: null };
    //相当于这样:let { x: x = 1 } = { x: null };
    console.log(x); // null

解构失败的话,变量值等于undefined

    let { x } = { y: 1 }
    console.log(x); // undefined

如果解构模式是嵌套的对象,子对象所对应的父属性不存在会报错

    let { x: { y } } = { y: y }
    console.log(y); //报错

对象的解构赋值,可以很方便的将现有对象的方法,赋值到某个变量

     //将Math对象的其中三个方法,赋值到对应变量上,使用起来会很方便
    let { abs, max, min } = Math;
    console.log(abs(-10)); //10
    console.log(max(1, 2)); //2
    console.log(min(1, 2)); //1

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

    let arr = [1, 2, 3];
    let { 0: first, [arr.length - 1]: last } = arr;
    //数组arr的下标(键)0 ,对应值是 1
    //[arr.length-1]就是数组arr的下标 2,对应的值是 3 
    console.log(first); // 1
    console.log(last); // 3