介绍
var a = 1; var b = 2; var c = 3;
可写成 var [a, b, c] = [1, 2, 3];
类似这种模式匹配,从数组和对象中提取值,对变量进行赋值的造作,就叫解构赋值。
用法
基本使用
let [foo, [[bar], baz]] = [1, [[2], 3]] // foo=1,bar=2,baz=3
let [x, ,y] = [1, 2, 3] //x=1,y=3
let [head, ...tail] = [1, 2, 3, 4] //head=1,tail=[2, 3, 4]
let [a, [b], d] = [1, [2,3], 4] //a=1,b=2,d=4当解构不成功,变量的值就为undefined.
let [x, y, ...z] = ['a'] //x='a',y=undefined,z=[]可用Set结构
let [x, y, z] = new Set([1, 2, 3])
很容易报的错***Uncaught SyntaxError: Identifier 'x' has already been declared***记得别用声明过的变量再声明。-
具有Iterator接口的都可以采用数组形式的解构赋值。
function* fib(){ var a = 0; var b = 1; while(true){ yield a; //执行到yield,停止执行,输出a的值 [a,b] = [b,a+b]; //a=b,b=a+b,此时的a的值为0,不会取得到刚赋的值 } } var [first, second, third, fourth, fifth, sixth] = fibs(); // 0 1 1 2 3 5
默认值
- 默认值是在变量严格等于
undefined时才使用的。
var [x = 1] = [undefined]; //x=1
var [x = 1] = [null]; //x=null - 可以引用解构赋值中的其他变量,但必须已声明。
let [x=1,y=x] = [2]; //x=2,y=2 默认值是取赋值后的值
let [x=1,y=x] = [1, 2]; //x=1,y=2
let [x=y,y=1] = []; //ReferenceError
let [x=y,y] = [2, x]; //'x' is not defined
声明有序,赋值无序,默认值是取赋值后的值。
对象的解构赋值
- 先找到key,再赋值
var {foo:baz} = { foo: "aaa"} // baz="aaa",foo is not defined
foo是模式,不是变量,不会被赋值。 - 重新声明会报错
let foo;
let {foo} = {foo:1}; //SyntaxError: foo has already decleared - 指定默认值(等号)
var {x=3} = {}; //x=3
字符串的解构赋值
const [a, b, c, d, e] = 'Hello'; //a='H',b='e',c='l',d='l',e='o'
let {length:len} = 'hello'; //len=5
数值和布尔值
- 如果等号右边的值是数值或布尔值,会先转换为对象
let {toString: s} = 123;
s === Number.prototype.toString //true
同样的,
let {toString: s} = true;
s === Boolean.prototype.toString //true -
undefined和null无法转为对象,会报错
let {prop: x} = undefined; //TypeError
let {prop: y} = null; //TypeError
函数的解构赋值
匹配
[[1, 2], [3, 4]].map(([a, b]) => a+b) //[3, 7]
[{g:1,k:4},{g:2,k:5},{g:9,k:9}].map(({g,k})=>g*k) //[4, 10, 81]-
默认值
// 变量的默认值
function move1({x = 0, y = 0} = {}){
return [x, y];
}
move1({x: 3, y: 8}); //[3, 8]
move1({x: 3}); //[3, 0]
move1({}); //[0, 0]
move1(); //[0, 0]/* -------------------------------------------------------------- */ // 参数的默认值, 没参数时用{x: 0, y: 0},指定参数,不是指定变量值 function move2({x, y} = {x: 0, y: 0}){ return [x, y]; } move2({x: 3, y: 8}); //[3, 8] move2({x: 3}); //[3, undefined] move2({}); //[undefined, undefined] move2(); //[0, 0]
圆括号
- 声明中模式不能有圆括号
var [(a)] = [1]; //报错 - 函数参数也属于声明,不能带
function f([(z)]) {return z;} //报错 - 不能将整个模式或嵌套模式中的一层放在括号中
({p: a}) = {p: 42}; // 报错 - 正确的写法(记得先声明哟)
let b;
...
[(b)] = [3];
[{p: (d) }] = {};
[(parseInt.prop)] = [3];