解构赋值
es6为我们对变量赋值提供了新的方式.
**方式1 : **
//ES5
var a = 1;
var b = 2;
var c = 3;
//这是在es6之前的赋值方式
//ES6
var [a,b,c] = [1,2,3];
console.log(a,b,c);
//变量会分别辅助到a,b,c中去, 因此输出结果为1,2,3;
const arr = ['a', 'b', 'c'];
const [name1, name2, name3] = arr;
//当然对于const, 和let的解构赋值也是可以的;
console.log(name1);
console.log(name2);
console.log(name3);
方式2 : **
本质是上述匹配属于一种模式匹配**, 也就是只要等号两边的模式相同,左边的变量就会被赋予对应的值。
let [foo,[[bar],baz]] = [1,[[2],3]];
console.log(foo,bar,baz);
//输出, 1 2 3
let [x,,y] = [1,2,3];
let [head,...tail] = [1,2,3,4,5];
// ...tail 把后续元素当成数组 如果 没有后续元素那么就是空数组。
let [a,b,...z] = ['a'];
console.log(x,y);
//输出, 1 3
console.log(head,tail);
//输出, 1 Array(4)
console.log(a,b,z);
//输出, a undefined Array(0)
如下情况会报错 右边不是数组(或者严格地说,不是可遍历的结构)
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
**方式3: **
默认赋值
只有右侧的值严格等于undefined的时候才生效。
var [foo = true] = [];
console.log(foo);//true
var [x1, y1 = 'b'] = ['a'];
console.log(x1,y1);//a, b
var [x2, y2 = 'b'] = ['a',undefined];
console.log(x2,y2);//a, b
//null 不等于undefined 所以不生效
var [x3 = 1] = [null];
console.log(x3);//null
**方式4: **
惰性求值 只有在用到的时候,才会求值
function f () {
return 'aaa';
}
let [x1 = f()] = [1];
let [x2 = f()] = [];
console.log(x1);//1
console.log(x2);//aaa
默认赋值规则
默认赋值可以应用解构赋值的其他变量
首先看右侧有无和左侧对应的值,没有的话看左侧从左到右解析
let [x1 = 1, y1 = x1] = [];
let [x2 = 1, y2 = x2] = [2];
let [x3 = 1, y3 = x3] = [1,2];
console.log(x1,y1);//1 1
console.log(x2,y2);//2 2
console.log(x3,y3);//1 2
let [x4 = y4, y4 = 1] = []; --var 和 let 有区别
console.log(x4,y4);//报错, let不具有变量声明提前
var [x4 = y4, y4 = 1] = []; --var 和 let 有区别
console.log(x4,y4);//undefined 1
**方式5: **
对象的解构赋值
对象的解构赋值是按照属性名称决定的
var {foo,bar} = {foo: 'aaa', bar: 'bbb'};
console.log(foo);//输出aaa
console.log(bar);//输出bbb
var {baz} = {foo: 'aaa', bar: 'bbb'};
console.log(baz);//输出undefined
**对象赋值注意: **一个已经声明的变量用于解构赋值 必须非常小心
var x;
// js引擎会将{x} 理解成一个代码块,从而发生语法错误。只有不将大括号写在行首可以避免这个问题
//{x} = {x:1};
({x} = {x:1});
console.log(x);
同时对象的结构赋值, 也可以用于嵌套结构
var obj = {
p: [
'hello',
{y: 'world'}
]
};
var {p: [x, { y }] } = obj;
console.log(x,y);//hello word
对象结构也可以自定默认值 默认生效条件和数组一样都是undefined
var {z = 3} = {};
console.log(z);//3
var {x, y = x} = {x:1};
console.log(x,y);//1 1
**方式6: **
字符串的解构赋值 字符串会转化成一个类数组的对象
const [a,b,c,d,e] = 'hello';
console.log(a,b,c,d,e);//h e l l o
类数组对象有length属性 所以len是5
let {length : len} = 'hello';
console.log(len);//5
**方式7: **
函数参数的解构赋值
函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被结构成变量 x 和 y
function add([x,y]) {
return x + y;
}
console.log(add([1, 2]));//3
练习
巩固一下上面的知识
function move({x = 0,y = 0} = {}) {
console.log([x,y]);
}
move({x:3,y:8});//3, 8
move({x:3});//3, 0
move({});//0, 0
move();//0, 0
function deal({x,y} = {x: 0 , y: 0}) {
console.log([x,y]);
}
deal({x: 3,y: 8});//3, 8
deal({x: 3});//3, undefined
deal({});//undefined undefined
deal();//undefined undefined
解构赋值用途
下面简单举例说明一下解构赋值的用途
1.交换变量
var x = 1;
var y = 2;
[x, y] = [y, x];
console.log(x, y);//2 1
2.从函数返回多个值
function example () {
return [1,2,3];
}
var [a, b, c] = example();//1 2 3
3.函数参数的定义
function f2({x,y,z}) {
console.log(x,y,z);//2 1 3
}
f2({z:3,x:2,y:1});
4.提交json数据
var jsonData= {
id: 42,
status: 'ok',
data:[888,999]
}
let {id,status,data:number} = jsonData;
console.log(id, status,number);//42 ok [888, 999]