深入理解 ES6 #5-解构:使数据访问更便捷
🏷️ 《深入理解 ES6》
ES6 为对象和数组都添加了解构功能,将数据解构打散的过程变得更简单,可以从打散后更小的部分中获取所需信息。
对象解构
let node = {
type: "Identifier",
name: "foo"
};
let {type, name} = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
解构赋值
let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5;
// 使用解构语法为多个变量赋值
// 注意:这里要在表达式的外层套一对小括号,否则{}会被视为一个代码块
({type, name} = node);
console.log(type); // "Identifier"
console.log(name); // "foo"
解构表达式的值与表达式右侧(也就是 =
右侧)的值相等。
let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5;
function outputInfo(value) {
console.log(value === node); // true
}
// 调用方法的同时使用解构表达式赋值
// 表达式的值为等号(=)右侧的值
outputInfo({type, name} = node);
console.log(type); // "Identifier"
console.log(name); // "foo"
默认值
使用解构表达式时,如果指定的局部变量名称在对象中不存在, name
这个局部变量会被赋值为 undefined
。
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined
也可以为不存在的局部变量定义默认值。
只有当解析对象中没有该属性或该属性值为 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
为非同名变量赋值
let node = {
type: "Identifier",
name: "foo"
};
// 使用解构语法为多个变量赋值
let {type: localType, name: localName} = node;
console.log(localType); // "Identifier"
console.log(localName); // "foo"
写法同对象字面量的语法相反,值在左边,变量在右边。
也可以在为非同名变量赋值的同时为其赋默认值。
let node = {
type: "Identifier"
};
// 使用解构语法为多个变量赋值
let {type: localType, name: localName = "bar"} = node;
console.log(localType); // "Identifier"
console.log(localName); // "bar"
嵌套对象解构
解构嵌套对象仍然与对象字面量的语法相似。
let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
};
let { loc: { start } } = node;
console.log(start.line); // 1
console.log(start.column); // 1
上例在解构模式中使用了花括号,其含义为在找到 node
对象中的 loc
属性后,应当深入一层继续查找 start
属性。
所有冒号前的标识符都代表在对象中的检索位置,其右侧为被赋值的变量名;
如果冒号后是花括号,则意味着要赋予的最终值嵌套在对象内部更深的层级中。
也可以使用一个与对象属性名不同的局部变量名。
let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
};
let { loc: { start: localStart } } = node;
console.log(localStart.line); // 1
console.log(localStart.column); // 1
数组解构
数组解构使用的是数组字面量,且解构操作全部在数组内完成。
let colors = [ "red", "green", "blue" ];
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";
[ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
使用数组解构交换两个变量的值
let a = 1,
b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1
默认值
当指定位置的属性不存在或其值为 undefined
时才会使用默认值。
let colors = [ "red" ];
let [ firstColor, secondColor = "green" ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
嵌套数组解构
与嵌套对象解构的语法类似。
let colors = [ "red", [ "green", "lightgreen" ], "blue" ];
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
方法实现)
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
console.log(clonedColors); // ["red", "green", "blue"]
Note
在被解构的数组中,不定元素必须为最后一个条目,在后面继续添加逗号会导致程序抛出语法错误。
混合解构
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 }) {
}
setCookie("type", "js", {
secure: true,
expires: 60000
});
第三个参数传入的是对象,方法参数使用参数解构自动提供属性值到对应的参数。
Note
解构参数支持上面所有的解构特性。
必须传值的解构参数
第三个参数不传或者为 null
、 undefined
时,解析会出错。需要为其提供默认值来解决这个问题。
function setCookie(name, value, { secure, path, domain, expires } = { }) {
}
解构参数的默认值
为解构参数中的某个或全部参数指定默认值
const setCookieDefaults = {
secure: false,
path: "/",
domain: "liujiajia.me",
expires: new Date(Date.now() + 360000000)
}
function setCookie(name, value, {
secure = setCookieDefaults.secure,
path = setCookieDefaults.path,
domain = setCookieDefaults.domain,
expires = setCookieDefaults.expires
} = setCookieDefaults) {
// ...
}