ES6:Object

190 阅读3分钟

1.1 对象属性声明简化


        var foo = 'foo'
        var bar = 'bar'
        let obj = {foo, bar}
        //等价于
        let obj = {
            foo: 'foo', bar: 'bar'
        }
    

    let person = {name:"jony",age:20}
    
    let {name,age} = data
    
    就相当于把person中的name的值赋值给name,把age的值赋值给到age
    
    console.log(name); // jony
    
    console.log(age); // 20
    

1.2 对象的解构赋值

解构不仅可以用于数组,还可以用于对象。

    var { foo, bar } = { foo: "aaa", bar: "bbb" };
    foo // "aaa"
    bar // "bbb"

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

    var { bar, foo } = { foo: "aaa", bar: "bbb" };
    foo // "aaa"
    bar // "bbb"
    
    
    var { baz } = { foo: "aaa", bar: "bbb" };
    baz // undefined
    //没有对应的同名属性,导致取不到值,最后等于undefined。

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

    let obj = { first: 'hello', last: 'world' };
    let { first: f, last: l } = obj;
    f // 'hello'
    l // 'world'

注意!!!

这实际上说明,对象的解构赋值是下面形式的简写
var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };
 
也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。
真正被赋值的是后者,而不是前者。

var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

上面代码中,真正被赋值的是变量baz,而不是模式foo。



注意,采用这种写法时,变量的声明和赋值是一体的。对于let和const来说,
变量能重新声明,所以一旦赋值的变量以前声明过,就会报错。
let foo;
let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo"

let baz;
let {bar: baz} = {bar: 1}; // SyntaxError: Duplicate declaration "baz"
 

上面代码中,解构赋值的变量都会重新声明,所以报错了。
不过,因为var命令允重新声明,所以这个错误只会在
使用let和const命令时出现。如果没有第二个let命令,
上面的代码就不会报错。

let foo;
({foo} = {foo: 1}); // 成功

let baz;
({bar: baz} = {bar: 1}); // 成功

2 数组的解构赋值

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

    以前,为变量赋值,只能直接指定值。
    var a = 1;
    var b = 2;
    var c = 3;
     
    ES6允许写成下面这样。
    可以从数组中提取值,按照对应位置,对变量赋值。
    var [a, b, c] = [1, 2, 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 // []
    
    
    如果解构不成功,变量的值就等于undefined。
    var [foo] = [];
    var [bar, foo] = [1];
    以上两种情况都属于解构不成功,foo的值都会等于undefined。

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

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

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


    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 { message: msg = 'Something went wrong' } = {};
    msg // "Something went wrong"