《Understanding ES6》chapter 5 Destructuring for Easier Data Access

207 阅读4分钟

2019-7-2

第五章 解构:更方便的数据访问

(一) 对象解构

​ 对象字面量 = 初始化器

注意: 不能漏掉初始化器,否则会抛出语法错误!!!

let node = {
        type: "Identifier",
        name: "foo"
    };

let { type, name } = node;

不是在声明时使用对象解构,其他地方使用要用圆括号包裹。因为暴露的花括号会被解析为代码块语句,而代码块语句是不允许出现在赋值操作符(=)左侧的。

let node = {
        type: "Identifier",
        name: "foo"
    },
    type = "Literal",
    name = 5;

// assign different values using destructuring
({ type, name } = node);

解构表达式的值为表达式右侧的值(即在=后侧的值),当解构表达式右侧的计算结果为null或者undefined时,会抛出错误。因为任何读取null或者undefined属性的企图都会导致”运行时“错误。

let node = {
        type: "Identifier",
        name: "foo"
    },
    type = "Literal",
    name = 5;

function outputInfo(value) {
    console.log(value === node);
}

// 对type,name正常赋值,同时将node传入outputInfo函数
outputInfo({ type, name } = node);        // true

当使用解构赋值语句时,如果所指定的本地变量在对象中没有找到同名属性,那么该变量会被赋值为undefined

let node = {
        type: "Identifier",
    };

let { type, value } = node;

console.log(type);      // "Identifier"
console.log(value);     // undefined

指定默认值:

let node = {
        type: "Identifier",
    };

let { type, value = true } = node;

console.log(type);      // "Identifier"
console.log(value);     // true

赋值给非同名变量:

let node = {
        type: "Identifier",
        name: "foo"
    };

// 可以看成是与传统的对象字面量语法相反,传统语法名称在左,值在右,而这里名称在右,值在左
let { type: localType, name: localName } = node; 

console.log(localType);     // "Identifier"
console.log(localName);     // "foo"

嵌套的对象解构

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

let { loc: { start }} = node;

console.log(start.line);        // 1
console.log(start.column);      // 1

2019-7-03

(二)数组解构

数组解构时,解构作用在数组内部的位置上,而不是作用在对象的属性名上。

let colors = [ "red", "green", "blue" ];

let [ firstColor, secondColor ] = colors;

console.log(firstColor);        // "red"
console.log(secondColor);       // "green"
  1. 和对象解构一样,不能漏掉初始化器;
  2. 在赋值表达式中使用数组解构,不必要将表达式包含在圆括号内;

数组解构小技巧: 可以轻易交换两个变量的值

// Swapping variables in ECMAScript 6
let a = 1,
    b = 2;

[ a, b ] = [ b, a ];

console.log(a);     // 2
console.log(b);     // 1

指定默认值:

let colors = [ "red" ];

let [ firstColor, secondColor = "green" ] = colors;

console.log(firstColor);        // "red"
console.log(secondColor);       // "green"

嵌套的解构

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;

console.log(firstColor);        // "red"
console.log(restColors.length); // 2
console.log(restColors[0]);     // "green"
console.log(restColors[1]);     // "blue"

可以用剩余项达到跟concat()相同的效果

// cloning an array in ECMAScript 6
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;  // 等价于clonedColors = colors.concat();

console.log(clonedColors);      //"[red,green,blue]"

(三)混合解构

将对象解构和数组解构混合使用,对从json配置结构中抽取数据尤其有用。

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

(四) 参数解构

参数解构:使用解构语法作为函数的参数,解构的参数可以是对象模式,数组模式或混合模式,并能使用解构的所有特性。

参数解构的优点:对参数顺序无要求,从函数的参数定义就可以看出函数所期望的输入。

解构参数不可缺失:调用函数如果没有给参数解构传值会抛出错误,如果解构参数是可选的,可以通过给解构的参数提供默认值来解决这个问题。

function setCookie(name, value, { secure, path, domain, expires }) {
		// 相当于
    let { secure, path, domain, expires } = options; // 所以当options为null或undefined 会报错
}

// 可以给解构的参数提供默认值
function setCookie(name, value, { secure, path, domain, expires } = {}) {
    // ...
}

参数解构的默认值:不能避免传入null时报错,因为只有传入值为undefined时,才会取到默认值。

function setCookie(name, value,
     // 给每个属性都提供了默认值,可以避免检查指定属性否已被传入
    {
        secure = false,
        path = "/",
        domain = "example.com",
        expires = new Date(Date.now() + 360000000)
    } = {} // 给整个解构的参数指定了默认值,让该参数成为可选参数
) {

    // ...
}