ES6学习笔记-解构-Destructuring
什么是解构
我们以访问数组中的前三个元素为例
传统的访问方式
let frist = array[0];
let second = array[1];
let third = array[2];
使用解构的特性
let [first, second, third] = array;
两段代码是完全等效的,利用新特性能使代码更加简洁和易读
数组与迭代器的解构
一般形式
let [variable1, variable2, ..., variableN] = array;
嵌套数组的解构
let [a, [[b], c]] = [1, [[2], 3]];
console.log(a); //1
console.log(b); //2
console.log(c); //3
留空跳过元素
let [,,c] = [1, 2, 3];
console.log(c); //3
结合不定参数
let [head, ...tail] = [1, 2, 3, 4];
console.log(tail); //[2, 3, 4]
越界时的结果
let [missing] = [];
console.log(missing); //undefined
在迭代器中的使用
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, forth, fifth, sixth] = fibs();
console.log(sixth); //5
对象的解构
一般形式
let { name: nameA } = { name: 'Lily' };
let { name: nameB } = { name: 'Lucy' };
console.log(nameA); //Lily
console.log(nameB); //Lucy
属性名与变量名一致时的简写
let { foo, bar } = { foo: 'foo', bar: 'bar' }
console.log(foo); //'foo'
console.log(bar); //'bar'
嵌套对象解构
let complicatedObj = {
arrayProp: [
'Zapp',
{ second: 'Brannigan' }
]
}
let {
arrayProp: [
first,
{ second }
]
} = complicatedObj;
console.log(first); //'Zapp'
console.log(second); //'Brannigan'
解构未定义的属性
let { missing } = {};
console.log(missing); //undefined
若变量已定义好,解构语句中不存在 let 等关键字
{ a } = { a: 10 }; //Syntax error 语法错误
(){ a } = { a: 10 }); //无语法错误
解构值不是对象、数组或迭代器
尝试解构 undefined 或者 null 时,会得到类型错误
let { blowUp } = null; //TypeError: null has no properties
然而,解构其他原始类型就不会报错,但是会得到 undefined
let { wtf } = NaN;
console.log(wtf); //undefined
原因:当使用对象赋值模式时,被解构的值会被强制转换为对象,null 和 undefined 无法进行转换所以出现错误。
默认值
let [missing = true] = [];
console.log(missing); //true
实际应用
函数参数定义
作为开发者,我们需要实现设计良好的API,通常的做法是为函数为函数设计一个对象作为参数,然后将不同的实际参数作为对象属性,以避免让API使用者记住 多个参数的使用顺序。我们可以使用解构特性来避免这种问题,当我们想要引用它的其中一个属性时,大可不必反复使用这种单一参数对象。
function removeBreakpoint({ url, line, column }) {
// ...
}
配置对象参数
当我们构造一个提供配置的对象,并且需要这个对象的属性携带默认值时,解构特性就派上用场了。举个例子,jQuery的ajax函数使用一个配置对象作为它的第二参数,我们可以这样重写函数定义:
jQuery.ajax = function (url, {
async = true,
beforeSend = noop,
cache = true,
complete = noop,
crossDomain = false,
global = true,
// ... 更多配置
}) {
// ... do stuff
};
如此一来,我们可以避免对配置对象的每个属性都重复var foo = config.foo || theDefaultFoo;这样的操作。
与迭代器协同使用
在迭代 Maps 时,可以得到一些列形如[key, value]的键值对,此时利用解构可以更轻松地访问键和值
let map = new Map();
map.set(window, 'the global');
map.set(document, 'the document');
for (let [key, value] of map) {
console.log(`${key} is ${valuel}`);
}
只遍历键
for (let [key] of map) {
//...
}
或只遍历值
for (let [, value] of map) {
//...
}
多重返回值
- 返回一个数组将结果解构
function returnMultipleValues() { return [1, 2]; } let [first, second] = returnMultipleValues();
- 用一个对象作为容器并为返回值命名
function returnMultipleValues() { return { first: 1, second: 2 } } let { first, second } = returnMultipleValues();
导入模块
const { SourceMapConsumer, SourceNode } = require("source-map");