数组基本用法
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为 解构(Destructuring)
var [a, b, c] = [1, 2, 3];
console.log(a, b, c); // 1 2 3
以上代码表示,可以从数组中直接提取值,按照对应的位置,对应变量赋值。只要两边等号的模式相同,左边的变量就会被赋予对应的值,我们称为模式匹配。如果解构不成功,变量的值就等于 undefind
等号左边模式,只要匹配一部分的等号右边的数组。这种情况下,解构依然成功,我们称为不完全解构
var [x, y] = [1, 2, 3];
console.log(x, y); // 1 2
如果等号右边不是数组(或者严格地说,不是可遍历的结构)。这种情况,结构将会报错
var [foo] = 1;
结构赋值不仅适用于 var 命令,也适用于 let 和 const 命令
let [x ,...y] = ['Hello' ,'ES6'];
console.log(x, y); // Hello ['ES6']
const [APPID,SECRET] = ['Destructuring','ESCMAScript6'];
console.log(APPID, SECRET); // Destructuring ESCMAScript6
对于 Set 结构,也可以使用数组解构赋值
let [x, y, z] = new Set(['Hello' , 'ESCMAScript6','World']);
console.log(x, y, z); // Hello ESCMAScript6 World
事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式写解构赋值,如 Generator函数 :
function* fibs(){
let a = 0;
let b = 1;
while(true){
yield a;
[a, b] = [b , a + b];
}
}
var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth); // 5
默认值
解构赋值允许指定默认值
var [defaultValue = 10] = [];
ES6 内部使用严格相等运算符( === ),判断一个位置是否有值。如果一个数组成员不严格等于 undefined,默认值是不会生效的
var [defaultValue = 10] = [null];
console.log(defaultValue); // null
如果默认值是一个表达式,那么这个表达式是惰性求值,即只有在用到的时候,才会求值
var f = function(){
return 20;
}
//没有用到 表达式
var [defaultValue3 = f()] =[1];
console.log(defaultValue3); // 1
//用到 表达式
var [defaultValue4 = f()] =[];
console.log(defaultValue4); // 20
默认值可以引用解构赋值的其他变量,但是这个变量必须已经声明
var [defaultValue5 = 1, defaultValue6 = defaultValue5] = [];
console.log(defaultValue5,defaultValue6);// 1 1
对象的解构赋值
解构不仅可以用于数组,还可以用于对象
var {foo , bar} = {foo : 'aaa', bar : 'bbb' };
console.log(foo, bar);// aaa bbb
对象解构与数组解构不同,数值解构是按照数组次序进行取值;对象解构是按照属性名取值,即变量名与属性名相同。
如果变量名与属性名不相同时,必须写成以下方式
var {foo : baz} = { foo :'Hello'};
console.log(baz);// Hello
对象的解构赋值的内部机制,是先找到同名的属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
变量的声明与赋值是一体的。对于let和const来说,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错。
let foo;
let {foo} = {foo:1}; // SyntaxError: Duplicate declaration "foo"
解构也可以用于嵌套解构的对象
var obj = {
p:[
"Hello",
{ world : "World" }
]
};
var { p :[hello,{world}]} = obj;
console.log(hello,world); // Hello World
这时 p 是模式,不是变量,因此不会被赋值
字符串的解构赋值
字符串也可以解构赋值。这是因为此时字符串被转换成了一个类似数组的对象
const [H, E, L, L2, O] = 'hello';
console.log(H,E,L,L2,O);// h e l l o
类似数组的对象都有一个 length 属性,因此还可以对这个属性解构赋值
let { length } = 'hello';
console.log(length); // 5
用途
- 交换变量的值
[x, y] = [y, x];
- 从函数返回多个值
var example = function(){
return ['hvkcoder', 18, 'coder'];
};
var [name, age, job] = example();
- 函数参数的定义
//有次序的值
function func([firstParm,secondParm]){
console.log(firstParm,secondParm); // Hello World
}
func(['Hello','World']);
//无次序的值
function funcNo({userName,passWorld}){
console.log(userName,passWorld); // hvkcoder 1234
}
funcNo({userName:'hvkcoder',passWorld:'1234'});
- 提取 JSON 值,解构赋值对提取 JSON 对象中的数据,尤其有用
var jsonData = {
id: 1,
data: [1,2]
};
let { id,data} = jsonData;// 1 [ 1, 2 ]
- 遍历Map结构
var map = new Map();
map.set('first','hello');
map.set('second','world');
for(let [key, value] of map){
console.log(key + ':' + value); // first : hello second : world
};
//获取键
for(let [key] of map){};
//获取值
for(let [,value] of map){}
小结
利用var,let结合数组解构,可以一次声明多个变量。特别是json数据的提取和变量的转换上,以及函数的默认参数传递上可以给默认值。解构赋值允许指定默认的值,有效的解决了函数返回多个变量的赋值问题,同时也解决了函数参数默认值的问题。