ES6解构
@(ES6大法) 来自个人的印象笔记分享
解构是将一个数据结构分解为更小的部分的过程。
1、解构为何有用?
let options = {
repeat: true,
save: false
};
// 从对象中提取数据
let repeat = options.repeat,
save = options.save
会不会觉得上面从对象中提取数据的代码很麻烦,写了很多相似的代码。
2、对象解构
可以用对象解构来简化:
let node = {
type: "Identifier",
name: "foo"
};
let { type, name } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
但是,用对象解构时,必须初始化,下面这些代码会抛错:
// 语法错误!
var { type, name };
// 语法错误!
let { type, name };
// 语法错误!
const { type, name };
如果想要用解构来覆盖已经声明并初始化好的变量,则需要加括号:
let node = {
type: "Identifier",
name: "foo"
},
type = "Literal",
name = 5;
// 使用解构来分配不同的值
({ type, name } = node);
console.log(type); // "Identifier"
console.log(name); // "foo"
括号去掉,变成代码块语句,而块语句不允许在赋值操作符(即等号)左侧出现。
解构赋值表达式的值为表达式右侧(在 = 之后)的值。可以在函数调用的时候传参使用:
outputInfo({ type, name } = node);
该表达式计算结果为 node。
解构还接受默认值:
let { type, name, value = true } = node;
如果node对象里没有value属性,vaule解构时又没赋予默认值,则value为undefined。
如果,你想给赋值的变量一个别名,不想和被解构的对象属性名称一致的话,你可以这样,并且也可以给别名一个默认值:
let { type: localType, name: localName = "bar" } = node;
对象解构还可以嵌套:
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
嵌套比较难理解,但是记住一些规定:
1)每当有一个冒号在解构模式中出现,就意味着冒号之前的标识符代表需要检查的位置,而冒号右侧则是赋值的目标
2)当冒号右侧存在花括号时,表示目标被嵌套在对象的更深一层中
同样可以用别名:
// 提取 node.loc.start
let { loc: { start: localStart }} = node;
console.log(localStart.line); // 1
console.log(localStart.column); // 1
3、数组解构
数组解构与对象解构的区别是,解构作用在数组内部的位置上,而不是作用在对象的具名属性上。
let colors = [ "red", "green", "blue" ];
let [ firstColor, secondColor ] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
可以忽略一些项,只提供需要的变量名:
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"
解构可应用在,交换a与b的值:
let a = 1,
b = 2;
[ a, b ] = [ b, a ];
数组解构也可以有默认值和嵌套解构:
let [ firstColor, secondColor = "green" ] = colors;
let colors = [ "red", [ "green", "lightgreen" ], "blue" ];
数组解构剩余项:
let colors = [ "red", "green", "blue" ];
let [ firstColor, ...restColors ] = colors;
console.log(firstColor); // "red"
console.log(restColors; // [ "green", "blue" ]
console.log(restColors[0]); // "green"
console.log(restColors[1]); // "blue"
剩余项可以应用在克隆数组:
// 在 ES5 中克隆数组
var colors = [ "red", "green", "blue" ];
var clonedColors = colors.concat();
console.log(clonedColors); //"[red,green,blue]"
// 在 ES6 中克隆数组
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;
console.log(clonedColors); //"[red,green,blue]"
4、混合结构
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
5、参数结构
ES5中:
// options 上的属性表示附加参数
function setCookie(name, value, options) {
options = options || {};
// 传进来的时对象的话,要一个个取出来
let secure = options.secure,
path = options.path,
domain = options.domain,
expires = options.expires;
// 设置 cookie 的代码
}
// 第三个参数映射到 options
setCookie("type", "js", {
secure: true,
expires: 60000
});
ES6中可以用参数结构告别上面的一大堆取值:
function setCookie(name, value, { secure, path, domain, expires }) {
// 设置 cookie 的代码
}
setCookie("type", "js", {
secure: true,
expires: 60000
});
当调用函数但是没有传解构的对象时,会报错,所以如果解构参数的部分是非必需时,可以给一个默认值,如果每一个参数都有默认值,这样:
function setCookie(name, value,
{
secure = false,
path = "/",
domain = "example.com",
expires = new Date(Date.now() + 360000000)
} = {}
) {
// ...
}