ES6允许按照一定的模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructing)。
数组的解构赋值
以前,为变量赋值,只能直接指定值
var a=1;
var b=2;
ES6中允许写成
var [a,b,c] = [1,2,3];
对于数组而言,解构赋值,就是按照对应的位置,对变量赋值
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
let [foo,[[bar],[baz]]] = [1,[[2],[3]]];
foo //1
bar //2
baz //3
let [head,...tail] = [1,2,3,4];
head //1
tail //[2,3,4]
let [x,y,...z] = ['a'];
x //a
y //undefined
z //[]
如果解构不成功,变量的值就是undefined
还有一种情况是不完全解构,即等号左边的模式,只匹配一部分等号右边的数组,这样的情况下依然可以解构成功
let [x,y] = [1,2,3];
x //1
y //2
如果等号右边的不是可遍历的结构,那么将会报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
上面的表达式都会报错
解构赋值允许指定默认值
var [foo = true] = [];
foo //true
当数组成员严格等于(===)undefined的时候,默认值可以生效
var [foo = true] = [1];
foo //1
var [baz = true] = [null];
baz //null
这个时候因为数组成员的值是1和null,所以默认值不生效
对象的解构赋值
解构不仅可以用于数组,还可以用于对象
var {foo,bar} = {foo:"aaa",bar:"bbb"};
foo //aaa
bar //bbb
对象的解构赋值的内部机制,是先找到同名的属性,然后再赋值给对应的变量。
var {foo:baz} = {foo:"aaa",bar:"bbb"};
baz //aaa
对于以上代码而言,被赋值的是baz而不是foo
因为let和const不能重复声明
let foo;
let {foo:baz}:{foo:"aaa",bar:"bbb"};
以上代码报错,因为foo重复声明。解构的变量都会重新声明
正确的写法
let foo;
({foo:baz}:{foo:"aaa",bar:"bbb"})
和数组一样,解构也可以用于嵌套解构
var obj = {
p:[
"hello",
{y:"world"}
]
};
var {p:[x,{y}]} = obj;
x //hello
y //world
注意,这边P是模式,不会被赋值
字符串的解构赋值
字符串被转换成一个类数组对象
const [a,b,c,d,e]="hello";
a //"h"
b //"e"
c //"l"
d //"l"
e //"o"
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值和布尔值,会先转为对象
函数参数的解构赋值
圆括号问题
ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号
建议只要有可能,就不要在模式中放置圆括号
(1)变量声明中不能带有圆括号
(2)函数参数中,模式不能带有圆括号
(2)赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号中
可以使用圆括号的情况:只有一种,赋值语句的非模式部分,可以使用圆括号
用途
(1)交换变量的值
[x,y] = [y,x];
(2)从函数返回多个值
function example(){return [1,2,3]};
var [a,b,c] = example();
(3)函数参数的定义
function f([x,y,z]){
//...
}
f([1,2,3]);
(4)提取JSON数据
var jsonData = {
id:42,
status:"ok",
data:[867,5309]
}
let {id,status,data:number} = jsonData;
console.log(id,status,number); //42,"ok",[867,5309]
(5)函数参数的默认值
Jquery.ajax = function(url,{async = true,cache = true}){
//do sth...
}
(6)遍历map解构
任何部署了Iterator接口的对象,都可以用for...of...循环遍历
var map = new Map();
map.set('first','hello');
map.set('second','world');
for(let [key,value] of map){
console.log(key + "is" + value);
}
(7)输入模块的指定方法
const{SourceMapConsumer,SourceNode} = require("source-map");
网友评论