ES6变量的解构赋值
简单的数组解构赋值:
let [a,b,c] = [1,2,3];
a//1
b//2
c//3
只要等号两边匹配,左边的变量就会被赋予对应的值。比如:
let[a,[b,c],[d],e]=[1,[2,3],[4],5];
e//5
…扩展符
…扩展操作符可以很方便的对数组和对象进行合并
var a = [1,2,3,4]
a//[1,2,3,4]
var a = [...a,5]
a//[1,2,3,4,5]
var b = [6,7,8]
var c = [...a,...b]
c//[1,2,3,4,5,6,7,8]
var a = {
Liming:{
age:12,
isMan:'yes'
},
Wangwu:{
age:18,
isMan:'no'
}
}
a/*Liming: {age: 12, isMan: "yes"}
Wangwu: {age: 18, isMan: "no"}*/
var Kangkang={
age:20,
isMan:'yes'
}
a={...a,Kangkang}
a/*Kangkang: {age: 20, isMan: "yes"}
Liming: {age: 12, isMan: "yes"}
Wangwu: {age: 18, isMan: "no"}*/
再说回解构赋值
var c = [1, 2, 3, 4, 5, 6, 7, 8]
var[x,y,...z]=c //...z要放在最后,不然会报错
x//1
y//2
z//[3,4,5,6,7,8]
如果解构不成功,变量的值就等于undefined。如:
var a = [1,2]
var[x,y,z]=a
x//1
y//2
z//undefind
如果等号右边的值比等号左边的属性多,那这就是不完全解构
var [a,b] = [1,2,3]//不完全解构
var [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
如果等号右边不是可遍历解构,那么就会报错,如:
let [foo] = 1;
let [foo] = false;//false is not iterable
let [foo] = NaN;//NaN is not iterable
let [foo] = undefined;//undefined is not iterable
let [foo] = {}
上面的表达式都会报错,因为等号右边的值,要么转为对象以后不具备Iterator接口(前四个表达式),要么本身就不具备Iterator接口(最后一个表达式)
解构赋值不仅适用于var命令,也适用于let和const命令。
解构赋值允许指定默认值。
let [foo='a'] = []
foo //'a'
[x, y = 'b'] = ['a']; // x='a', y='b'
[x, y = 'b'] = ['a', undefined]; // x='a', y='b'
解构不仅可以用于数组,还可以用于对象。
var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
需要注意的,在对对象进行解构时,不能直接按照顺序来解构,因为对象的属性是没有顺序的,所以变量名要与对象的属性名一致才能进行解构
/*解构正确*/
var {a,b} = {a:1,b:"sss"}
a//1
b//"sss"
/*对象解构无序*/
var{name,age,tel} = {age:18,tel:"18154112211",name:"胡图图",father:"胡英俊"}
name//"胡图图"
如果变量名与属性名不一致,必须写成下面这样。
var {name:son} = {age:18,tel:"18154112211",name:"胡图图",father:"胡英俊"}
son//"胡图图"
这实际上说明,对象的解构赋值是下面形式的简写
var {a:a,b:b} = {a:1,b:"sss"}//相当于var {a,b} = {a:1,b:"sss"}
那么就是说,其实在对象的解构赋值中,他是先找到对象的同名属性,在将值赋给冒号后面的变量。
要注意的是解构赋值的属性即使解构失败,依然已经被定义,如果使用let声明变量的话,则会出现重复声明的情况
和数组一样,解构也可以用于嵌套结构的对象。
var obj = {
p: [
'Hello',
{ y: 'World' }
]
};
var { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
对象的解构也可以指定默认值。
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var {x:y = 3} = {};
y // 3
var {x:y = 3} = {x: 5};
y // 5
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
var {parent:{son}} = {son:"李立"}//Cannot destructure property `son` of 'undefined' or 'null'.
之所以会出现这样的情况,是因为此时parent是undefined,就好比是:
var temp = {son:"李立"}
temp.parent.son//Cannot read property 'son' of undefined
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。比如:
let { max, sin, cos } = Math;
//这样就可以直接使用max等方法
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
函数参数的解构
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
[[1,2,6],[4,5,8],[7,8,9]].map(([x,y,z])=>x+y+z)
//[9, 17, 24]
解构赋值的用途
首先是可以交换变量的值
let [a,b,c] = [1,2,3]
a//1
b//2
c//3
[a,b,c] = [c,b,a]
a//3
b//2
a//1
从函数返回多个值
一般来说函数只能有一个返回值,但是我们可以利用解构赋值来让他返回一个数组来活动多个值
function a(){
return [5,6,7]
}
let[x,b,c] = a();
函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。
// 返回一个数组
function example() {
return [1, 2, 3];
}
var [a, b, c] = example();
// 返回一个对象
function example() {
return {
foo: 1,
bar: 2
};
}
var { foo, bar } = example();
解构赋值可以方便地将一组参数与变量名对应起来。
// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
解构赋值对提取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]
任何部署了Iterator接口的对象,都可以用for…of循环遍历。Map结构原生支持Iterator接口,配合变量的解构赋值,获取键名和键值就非常方便。
加载模块时,往往需要指定输入那些方法。解构赋值使得输入语句非常清晰。
import React, { Component, Fragment } from "react";