为什么要使用解构
var obj = {
name:'Jon',
age:22
};
var name = obj.name;
var age = obj.age;
上面代码是我们以前开发时经常要使用的,从对象和数组中获取数据,并给变量赋值;当对象和数组的数据结构比较复杂时,这种方法就比较麻烦了,有时需要一个个或者遍历;所以ES6添加了解构功能;将数据结构打散的过程变得更加简单,可以从打散后更小的部分中获取所需的信息。
数组解构
1、基本用法
以前,为变量赋值:
let a = 1;
let b = 2;
let c = 3;
ES6赋值:
let [a,b,c] = [1,2,3];
console.log(a);//1
console.log(b);//2
console.log(c);//3
数组解构使用的是数组字面量,且解构操作全部在数组中完成;上面代码中,从数组[1,2,3]中分别解构出来1,2,3这三个值,并赋值给a,b,c;这种写法本质上属于“模式匹配”,只要等号两边的模式相同,就可以通过值在数组中的位置进行选取,并且相对应的赋值;
2、设置默认值
数组解构允许在任意位置指定默认值,当指定位置的元素其值不存在或者为undefined的时候,使用其默认值;
let [x = 3] = [1];
console.log(x);//1
let [y = 4] = [];
console.log(y);//4
let [z = 5] = [undefined];
console.log(z);//5
let [a = 2] = [null];
console.log(a);//null
如果一个数组成员是null,默认值不会生效,因为null === undefined为false;
3、嵌套数组解构
当数组里嵌套一个数组时,即可将数组解构过程深入下一层;
let [a,b,[c,d],e] = [1,2,[3,4],5];
console.log(a);//1
console.log(c);//3
4、解构失败和不完全解构
解构失败出现是因为左边数组的元素比右边的元素多,这样就造成左边变量的值为undefined;
let [a] = [];
console.log(a);//undefined
let [b,c,d] = [1,2];
console.log(b);//1
console.log(c);//2
console.log(d);//undefined
不完全解构表示左边的数组元素比右边的元素少,只能匹配部分右边的元素;
let [a, b, c] = [1, 2, 3, 4];
console.log(a);//1
console.log(b);//2
console.log(c);//3
let [x, [y]] = [1, [2,3]];
console.log(x);//1
console.log(y);//2
如果等号的右边不是数组,那么将会报错;
5、交换变量的值
通常我们要交换两个变量的值都需要使用到第三个变量;
let x = 1;
let y = 2;
let tmp;
tmp = x;
x = y;
y = x;
现在我们使用ES6的数组解构能很方便的实现:
let x = 1;
let y = 2;
[x,y] = [y,x];
console.log(x);//2
console.log(y);//1
对象解构
1、基本用法
对象解构语法形式是在一个赋值操作符左边放置一个对象字面量:
let obj = {
name:'Jon',
age:22
};
let {name,age} = obj;
console.log(name);//'Jon'
console.log(age);//22
在上面代码中,obj.name解构储存在变量name中,obj.age解构储存在变量age中;对象的解构和数组有一个重要的不同,就是对象的属性没有次序,只要变量名和属性名相同就行;
let {age,name} = obj;
console.log(name);//'Jon'
console.log(age);//22
2、设置默认值
和数组解构一样,对象解构也可以设置默认值;
let {x = 3} = {};
console.log(x);//3
let {y,z = 3} = {y:5};
console.log(y);//5
console.log(z);//3
let {a = 3 ,b} = {};
console.log(a);//a
console.log(b);//undefined
let {c = 3} = {c:undefined};
console.log(c);//3
let {d = 3} = {c:null};
console.log(d);//3
从上面代码中可以看出,当对象的属性值为undefined或者为空时,默认值才会生效;
3、设置别名
我们现在有这么一个场景,后台给的JSON数据里的属性名和前端定义的变量值不一样;那么就可以通过设置别名来进行结构:
let obj = {
foo:'Hello',
bar:'World'
};
let {foo:name,bar} = obj;
console.log(name);//Hello
console.log(bar);//World
console.log(foo);//error:foo is not defined
从上面的代码看出,obj.foo的值赋值给变量name;在这里foo已经不是变量,只是匹配模式,所以无法找到;对象解构赋值的内部机制,是先找到同名属性,然后在赋值给对应的变量;
4、嵌套解构
和数组解构一样,对象解构也可以嵌套:
let obj = {
line: {
start: {
row: 2,
column: 3
},
end: {
row: 3,
column: 4
}
},
circle: 9
};
let {line, line: {start}, line: {start: {row}}, circle} = obj;
console.log(line);//{start:{row:2,column:3},end:{row:3,column:4}}
console.log(start);//{row:2,column:3}
console.log(row);//2
console.log(circle);//9
5、已声明变量的解构
给一个已声明的变量解构,是一件很麻烦的事;如果按照以前的方法:
let x ;
{x} = {x:1};//error
会报错,因为JavaScript引擎会将{x}理解城代码块,从而发生语法错误;那如何避免JavaScript将其解释为代码块,就只有让大括号不写在行首;
let x;
({x} = {x:1});
console.log(x);//1
上面代码将整个解构赋值语句,放在一个圆括号里面,就可以正确执行。
函数参数解构
1、基本用法
function fn([x, y]) {
console.log(x + y);
}
fn([1, 2]);//3
function fn2({x, y}) {
console.log(x * y);
}
fn2({x:1,y:2});//2
从上面代码可以看出,函数参数的解构其实就是变成数组的解构或者对象的解构;
2、设置默认值
函数参数解构可以设置默认值,这样就可以避免缺少值而报错的情况;
function fn({x = 2,y = 3} = {}) {
console.log([x,y]);
}
fn({x:3,y:4});//[3,4]
fn({x:3});//[3,3]
fn({});//[2,3]
fn();//[2,3]