es6 解构用法:对 object 和 array 解构

参考文档:《Understanding ECMAScript 6》《深入理解ES6》

https://book.douban.com/subject/26864806/ (英文版+中文版)


 解构目的:为了使代码更简单、简洁

解构对象:object 和 array
【注意】

  • 针对对象和数组,使用语法不同。
  • 一定要注意同样的符号出现在 = 左边和右边是不同的含义!!
  • 解构时必须初始化(let, var, const),否则会报语法错误。
  • object通过属性名访问对象,所以解构时用属性名作为新变量名;数组通过索引访问,所以解构时也只和索引位置有关。
  • 解构对象时:
    • 原有属性可设置别名,但不可设置默认值(设置了不报错也不启用默认值)
    • 嵌套解构只新建最内层{ }中的属性名
    • 冒号后面有{ } 是内层解构,冒号后面直接是变量名字则是别名
  • 解构数组时:
    • 设置的默认值只有指定位置的变量不存在或其值未定义时才起效
    • 嵌套解构时 = 左边 [ ] 中的变量都存在,但都是单个的值
    • 用扩展运算符... 可以把剩余的值都放到一个变量中,但这个变量在解构中必须是最后一个变量

一、 对象解构

1.1 基础用法

 = 左边用 var, let 或 const 声明,然后一个 { } 包裹要新建的局部变量; = 右边是原始的对象。

左边用 { } 括起来是解构对象的语法,可以简单理解为右边是对象,所以左边也要是对象。

        let node = {
            type: "Identifier",
            name: "foo"
        };
        
        //因为右边是对象,所以左边也要是对象,所以用{}括起来,里面的type、name是原始变量的属性
        let { type, name } = node; 
        console.log(type); // "Identifier"
        console.log(name); // "foo"

单独的属性变量已经被定义后,想修改为原始对象的初始值:

type and name are initialized with values when declared, and then two variables with the same names are initialized with different values.

圆括号()让代码块变成表达式,表达式的值是 = 右侧的值。对象解构重新赋值时一定要加圆括号(),数组解构重新赋值不用加圆括号()

        let node = {
            type: "Identifier",
            name: "foo"
        },
// change the values of variables after they’re defined, type
= "Literal", name = 5; // assign different values using destructuring ({ type, name } = node); console.log(type); // "Identifier" console.log(name); // "foo"

1.2 解构设置默认值(原有属性不可设置默认值,只有新属性才变量会使用默认值,因为新属性变量时原始对象中不存在的属性

 如果 = 左边有原始对象没有的属性名,则默认赋 undefined ,设置了默认值则为默认值。

        let node = {
            type: "Identifier",
            name: "foo"
        };
        let { type, name, value } = node;//value不设置默认值就是 undefined 
        console.log(type); // "Identifier"
        console.log(name); // "foo"
        console.log(value); // undefined
    -- 给新属性赋值和设置默认值
        let node = {
            type: "Identifier",
            name: "foo"
        };
        let { type, name, value = true } = node;
        console.log(type); // "Identifier"
        console.log(name); // "foo"
        console.log(value); // true

【注意】原有属性可设置别名,但不可设置默认值。(设置了不会报错,但也不会使用默认值,而是使用从解构获取的对象中的值)

When you use a destructuring assignment statement and you specify a local variable with a property name that doesn’t exist on the object, that local variable is assigned a value of undefined.

You can optionally define a default value to use when a specified property doesn’t exist.

        let node = {
            type: "Identifier",
            name: "foo"
        };
        let { type, name } = node;
        console.log(type); // "Identifier"
        console.log(name); // "foo"
        let node = {
            type: "Identifier",
            name: "foo"
        };
        // 给原有属性设置默认值无效,因为其值不是 null 或 undefined
        let { type, name="new name" } = node;
        console.log(type); // "Identifier"
        console.log(name); // "foo"

1.3 给原对象中属性起别名

        let node = {
        type: "Identifier"
        };
        // {原属性:别名}
        let { type: localType, name: localName = "bar" } = node;
        console.log(localType); // "Identifier"
        console.log(localName); // "bar"

1.4 嵌套解构

        let node = {
            type: "Identifier",
            name: "foo",
            loc: {
                start: {
                    line: 1,
                    column: 1
                },
                end: {
                    line: 1,
                    column: 4
                }
            }
        };

针对上面这个嵌套的对象,可以使用嵌套解构,但要注意:最后新建的本地变量只有最内层解构,外侧的loc变量并不存在!!

 

冒号后面有{ } 是内层解构,冒号后面直接是变量名字则是别名。

 

        // 此时loc变量不存在,存在的是start变量(解构出的变量是最内层{})
        let { loc: { start }} = node;
        console.log(start.line); // 1
        console.log(start.column); // 1
        console.log(loc); // 报错 Uncaught ReferenceError: loc is not defined

嵌套解构使用别名:

        // 冒号后面有{}是内层解构,冒号后面直接是变量名字则是别名
        let { loc: { start: localStart }} = node;
        console.log(localStart.line); // 1
        console.log(localStart.column); // 1

 二、数组解构

2.1 基础用法

 = 左边用 var, let 或 const 声明,然后一个 [ ] 包裹要新建的局部变量; = 右边是原始数组。

左边用 [ ] 括起来是解构数组的语法,可以简单理解为右边是数组,所以左边也要是数组。

        let colors = [ "red", "green", "blue" ];
        // Those values are chosen because of their position in the array; 
        // the actual variable names could be anything. 
        let [ firstColor, secondColor ] = colors;
        console.log(firstColor); // "red"
        console.log(secondColor); // "green"
        // 只要第三个位置的元素值
        let colors = [ "red", "green", "blue" ];
        let [ , , thirdColor ] = colors;
        console.log(thirdColor); // "blue"

单独的变量已经被定义后,想修改为原始数组的初始值:

        // 通过解构获得原始数组的值(无需圆括号())
        let colors = [ "red", "green", "blue" ],
        firstColor = "black",
        secondColor = "purple";
        // The only difference is that firstColor and  secondColor have already been defined.
        [ firstColor, secondColor ] = colors; // 数组解构时无需圆括号,对象解构时需要圆括号
        console.log(firstColor); // "red"
        console.log(secondColor); // "green"

2.2 数组解构的妙用:交换变量值

        // swapping variables in ECMAScript 6
        let a = 1,
        b = 2;
        // [] 在等号左边是解构,[]在等号右边是数组
        // 一定要注意同样的符号出现在 = 左边和右边是不同的含义!!
        // 解构,第一位置的变量值等于右边数组中索引为0的值,即 已定义的变量a被赋值为[b,a]数组i=0的值,也就是b
        // 同理,变量b被重新赋值为i=1的数组值a
        [ a, b ] = [ b, a ];
        console.log(a); // 2
        console.log(b); // 1

2.3 解构时设置默认值

只有当指定位置的属性不存在或其值未定义时,才会使用默认值。

        let colors = [ "red" ];
        // Array destructuring assignment allows you to specify a default value for any position in the array, too.
// The default value is used when the property at the given position either doesn’t exist or has the value undefined .
let [ firstColor, secondColor = "green" ] = colors; console.log(firstColor); // "red" console.log(secondColor); // "green"

2.4 嵌套解构

外层解构的新变量也存在,但只会按照索引位置取一个值而不是数组,如果想让最后一个变量是数组,需要使用扩展运算符...

Rest items use the ... syntax to assign the remaining items in an array to a particular variable.

        let colors = [ "red", [ "green", "lightgreen" ], "blue" ];
        // later
        let [ firstColor, [ secondColor ] ] = colors;
        console.log(firstColor); // "red"
        console.log(secondColor); // "green"

使用扩展运算符... 必须是最后一个变量,且后面不能有逗号

        let colors = [ "red", "green", "blue" ];
        let [ firstColor, ...restColors ] = colors;//restColors 是数组
        console.log(firstColor); // "red"
        console.log(restColors.length); // 2
        console.log(restColors[0]); // "green"
        console.log(restColors[1]); // "blue"

 三、混合解构

    let node = {
        type: "Identifier",
        name: "foo",
    loc: {
        start: {
            line: 1,
            column: 1
        },
        end: {
            line: 1,
            column: 4
        }
    },
    range: [0, 3]
    };
    
    let { 
        loc: { start },
        range: [ startIndex ]
    } = node;
    
    console.log(start.line); // 1
    console.log(start.column); // 1
    console.log(startIndex); // 0

我觉得这样太复杂了,不过书上写这样十分有效,因为不用遍历整个json结构了。。

This approach is particularly useful for pulling values out of JSON configuration structures without navigating the entire structure.

posted @ 2024-08-26 14:36  sunshine233  阅读(83)  评论(0编辑  收藏  举报