第五章 解构
《深入理解ES6》—— Nicholas C. Zakas
1. 析构的用处
在ES6之前,从对象或数组中获取信息,并将特定数据存入本地变量,
需要书写许多相似的代码:
let options = {
repeat: true,
save: false
}
// 从对象中提取数据
let repeat = options.repeat,
save = options.save;
此段代码提取了 options
对象的属性,并将其存在同名的本地变量上。
虽然简单,但如果有大量的属性要处理,则需要逐个为其赋值;
若数据嵌套很深,则还需要遍历。
这就是ES6为何要给对象与数组添加解构。
当把数据结构分解为更小的部分时,从中提取你要的数据会变得容易许多。
2. 对象解构
2.1. 语法
// 解构赋值表达式
对象字面量 = 初始化器
解构赋值表达式 的值为 初始化器的值。
对象字面量的属性标识符:既声明了本地变量,也读取了对象的相应属性值。
2.2. 解构赋值
声明的同时进行初始化赋值:
let person = {
name: "吴钦飞",
gender: "男"
}
let { name, gender } = person;
name; //=> "吴钦飞"
改变变量的值:
let person = {
//name: "吴钦飞",
gender: "男"
},
name = "张三",
gender = "未知";
// 如果不用小括号包裹解构表达式,花括号部分会当成代码块
( { name, gender } = person );
name; //=> undefined
在使用解构赋值时,如果指定的本地变量在对象中没有找到同名属性,
则赋值undefined
,会覆盖该变量原本的值。
2.3. 默认值
可以在对象字面量中指定默认值,
在本地变量找不到对应的属性或对应属性值为undefined
时,才会使用默认值。
let person = {
//name: "吴钦飞",
gender: "男"
},
name = "张三",
gender = "未知";
// 如果不用小括号包裹解构表达式,花括号部分会当成代码块
( { name = "帅哥", gender } = person );
name; //=> "帅哥"
2.4. 属性与变量不同名
let person = {
name: "吴钦飞",
gender: "男"
};
// 别名,默认值
let { name: myName, gender: myGender = "男" } = person;
myName; //=> 吴钦飞
2.5. 嵌套的对象解构
深入到嵌套的对象结构中去提取数据。
冒号左侧的标识符 代表 需要检查的位置,
冒号右侧是赋值的目标;
当冒号右侧存在花括号时,表示目标被嵌套在对象的更深一层。
let person = {
name: "吴钦飞",
loc: {
province: {
code: "42",
name: "湖北"
}
}
};
let {
loc: {
province: {
name
}
}
} = person;
name; //=> 湖北
3. 数组解构
3.1. 语法
数组字面量 = 初始化器
解构作用在数组内部的位置上。
let colors = [ "0_red", "1_green", "2_blue" ];
let [ firstColor, secondColor ] = colors;
firstColor; //=> "0_red"
secondColor; //=> "1_green"
// 忽略一些值
let [ , , thirdColor ] = colors;
thirdColor; //=> "2_blue"
3.2. 互换变量值
let person = "张三";
let animal = "狗";
[ person, animal ] = [ animal, person ];
person; //=> "狗"
3.3. 默认值
let colors = [ "0_red" ];
let [ firstColor, secondColor = "1_green" ] = colors;
secondColor; //=> "1_green"
3.4. 嵌套
let colors = [ "0_red", [ "1_0_green" ], "2_blue" ];
let [ firstColor, [ secondColor ] ] = colors;
secondColor; //=> "1_0_green"
3.5. 剩余项
let colors = [ "0_red", "1_green", "2_blue" ];
let [ firstColor, ...restColors ] = colors;
restColors; //=> ["1_green", "2_blue"]
// 克隆数组
let es5ClonedColors = colors.concat();
let [...es6ClonedColors] = colors;
4. 混合解构
用于从JSON配置解构中抽取数据。
let config = {
entry:{
main:"./src/main.js"
},
module:{
rules:[
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["env"],
plugins: ["transform-runtime"]
}
}
}
]
}
};
let {
entry: { main },
module: {
rules:[
{
use: {
options: {
presets: [ preset ]
}
}
}
]
}
} = config;
main; //=> "./src/main.js"
preset; //=> "env"
5. 参数解构
5.1. 说明
当给函数传递大量可选参数时,以前,使用 options
:
function setCookie( name, value, options ) {
let
path = options.path,
domain = options.domain,
expires = options.expires
;
// ......
}
setCookie( "type", "js", {
expires: 60000
} );
无法仅通过查看函数定义就判断出函数所期望的输入,使用解构:
function setCookie( name, value, { path, domain } ) {
// ......
}
5.2. 解构的参数是必传参数
解构参数实际上是解构声明的简写:
function setCookie( name, value, options ) {
let { domain, expires } = options;
}
一旦 options
为 undefined
,就会报错,可以使用函数的参数提供默认值:
function setCookie( name, value, { domain, expires } = {} ) {
// ......
}
5.3. 解构参数的默认值
function setCookie( name, value,
{
domain = "baidu.com",
expires = 100000
} = {}
) {
// ......
}