ES6中引入了解构的特性,允许我们以一种更简短的方式来实现数组、对象成员赋值给各种变量
一、传统场景
我们想要提取数组中的元素到不同的变量中,传统做法如下:
var arr = ['A', 'B', 'C'];
var a = arr[0]; // 'A'
var b = arr[1]; // 'B'
var c = arr[2]; // 'C'
但是使用解构语法,只需要这么写:
var [a, b, c] = arr;
console.log(a, b, c); // 'A' 'B' 'C'
那么接下来,来详细了解下解构语法的用法吧
二、数组解构
数组的解构,只需要左边构造类似于右边的形式,就能提取出右边的值,如:
var [a, b] = ['Hello', 'world'];
// 得到a的值为'Hello',b的值为'World'
对于嵌套的案例,这条规则仍然适用:
var [a, [[[b]]]] = ['Hello', [[['World']]]];
我们在解构体前面可以加入var
、const
、let
,如此一来,将会在解构的同时声明变量、常量,如果不加入这些关键字,那么实现的则是赋值
问:如何只提取部分元素?
有时候,我们可能并不需要提取全部的元素,而是想提取部分元素,那么这种情况下,我们可以使用如下的形式:
var [,,c] = ['A', 'B', 'C'];
// 得到c的值为'C'
此外,还有以下的这种提取形式:
var [head, ...tail] = [1, 2, 3, 4, 5];
// 得到 head 的值为 1,tail的值为[2, 3, 4, 5]
当我们访问空的数组或者越界的索引时,对其解构,行为和对数组索引的行为一致,得到的都是undefined,如:
var [a] = [];
// a的值为undefiend
此外,我们还可以结合generator来使用解构,如:
function* gen () {
for (let i=0; i<5; ++i) {
yield i;
}
}
var [a, b, c, ...d] = gen();
/*
得到的结果:
a -> 0
b -> 1
c -> 2
d -> [3, 4]
*/
我们还可以指定当数组的某一个成员不存在时的默认值,如:
var [a = 5] = [];
// 得到a的值为5
三、对象解构
对象的解构,核心也是构造一个左边的模式,来匹配右边的模式,如:
var { name: _name, age: _age } = {
name: 'RuphiLau',
age : 21
}
// 得到的结果为:_name -> 'RuphiLau',_age -> 21
当解构体的key
和value
名称一样时,可以简写,即:
var { name: name, age: age } = { name: 'RuphiLau', age: 21 }
// 可以简写为:
var { name, age } = { name: 'RuphiLau', age: 21 }
可以进行嵌套解构,如:
var obj = {
catalogName: '电影',
list: [
'加勒比海盗',
'变形金刚'
],
info: [
{score: 9.0}
]
};
var {catalogName, list: [ ...movies ], info: [{score}]} = obj;
/*
可以得到:
catalogName -> '电影'
movies -> ["加勒比海盗", "变形金刚"]
score -> 9.0
*/
解构对象的时候,如果不同时赋值,那么像以下这种写法会报错:
{ a, b } = { a: 1, b: 2 };
这是因为以{
开头的,会被JavaScript引擎认为是块语句,从而产生二义性问题。要解决这个问题,可以使用一对圆括号包裹,如:
({a, b} = { a: 1, b: 2})
对象中的解构,也可以有默认值,用于对未定义值取默认值,如:
var { a = 1 } = {};
// a的值为1
var { error: code = 500 } = {};
// code的值为500
四、解构的应用
解构语法有着很广泛的应用,使用解构可以使得我们写出更简短易读的代码,以下总结几种常用的应用
1、函数参数中应用
我们可能希望有这样子的函数API:不需要记住它的参数顺序,只需要传入一个名称,它就会自动匹配,使用解构便可以达到这种效果,如下:
function ajax({
url,
method,
cbOnload,
cbOnerror
}) {
console.log('配置信息为:');
console.log(url, method, cbOnload, cbOnerror);
}
使用时候,就可以如:
ajax({url: '//ruphi.cn'});
ajax({method: 'GET', url: '//ruphi.cn'});
// 等等
如此一来,我们便能够更加语义化地调用一个函数。
此外,在传统情况下,JavaScript中是不能定义参数默认值的,而我们一般使用以下的形式来定义一个参数的默认值,如:
function toast(message, delay) {
delay = delay || 1000;
// ...
}
使用了解构语法,我们就无需再这么做了,只需要如:
function toast({
message,
delay = 1000
}) {
// ...
}
2、多重返回值
可以使用解构来得到一个函数的多重返回值,如:
function multiResult () {
return [1, 2, 3];
}
// 传统情况下:
var res = multiResult();
var a = res[0]; // 1
var b = res[1]; // 2
var c = res[2]; // 3
// 使用解构:
[a, b, c] = multiResult();
3、导入部分CommonJS模块
可以使用解构的形式,来导入部分CommonJS模块,如:
const { SourceMapConsumer, SourceNode } = require('source-map');