数组的结构赋值
什么是解构(Destructing)
ES6 允许按照一定模式从数组和对象中提取之后,然后对变量进行赋值
let [a, b, c] = [1, 2, 3];
console.log(a); //1
console.log(b); //2
console.log(c); //3
"模式匹配": 只要等号两边的模式相同,左边的变量就会被赋予对应的值
特性
可以使用嵌套数组进行解构
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3
let [head, ...tail] = [1, 2, 3, 4]; //变量名前有 ... 表示是数组
console.log(head); //1
console.log(tail); // [2,3,4]
不完全解构,等号左边的模式值匹配一部分的等号右边的数组
let [x, y] = [1, 2, 3];
console.log(x); //1
console.log(y); //2
解构赋值允许指定默认值
let [foo = true] = [];
console.log(foo); //true
let [x, y="b"] = ["a", undefined]
console.log(x); //a
console.log(y); //b
1.数组成员为undefined
let [x = 1] = [ undefined ];
console.log(x); //1
2.数组成员为null
let [ x = 1] = [ null ];
console.log(x); //null
3.默认值是一个表达式,这个表达式是惰性求值,即只有用到时才会求值
function f() {
console.log('aaa')
}
let [x = f()] = [1];
console.log(x); //x=1 因为x能取到值,所以函数f不会执行
//let [x = f()] = [1];等价于
let x;
if([1][0] === undefined){ //[1][0]表示的是数组的第1个元素
x = f(); //当数组成员严格等于undefined时,默认值才会生效
}else{
x = [1][0]
}
4.默认值可以引用解构赋值的其他变量,但是该变量必须已经声明
let [x = 1, y = x] = []; //x=1; y=1
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 因为x用到默认值y时,y还没有声明
解构不成功,变量的值为undefined
let [x] = [];
console.log(x); //undefined
报错: 等号的右边不是数组(或者不是可以遍历的结构)
let [foo] = 1; //Uncaught TypeError: 1 is not iterable
let [foo] = false; //Uncaught TypeError: false is not iterable
let [foo] = NaN; //Uncaught TypeError: NaN is not iterable
let [foo] = undefined; //Uncaught TypeError: undefined is not iterable
let [foo] = null; //Uncaught TypeError: null is not iterable
let [foo] = {}; //Uncaught TypeError: {} is not iterable
对象的解构赋值
对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量。真正被赋值的是后者,而不是前者
数组的元素是按次序排列的,变量的取值由它的位置决定
对象的属性没有次序,变量必须与属性同名才能取到值
let { foo, bar} = { foo: 'aaa', bar: 'bbb'}
console.log(foo); //aaa
console.log(bar); //bbb
没有同名属性,返回undefined
let { hello } = { foo: 'aaa', bar: 'bbb'}
console.log(hello); //undefined
变量名与属性名不一致
let obj = {
first: 'hello',
last: 'world'
}
let {first: f, last: l} = obj;
console.log(f); //hello
console.log(l); //world
将一个已经声明的变量用于解构赋值,要用()括起来
let x;
{x} = {x: 1}; //Uncaught SyntaxError: Unexpected token =
//正确写法
let x;
({x} = {x: 1});
console.log(x); // 1
解构失败,变量的值为undefined
let {foo} = {bar: 'bar'}
console.log(foo); //undefined
字符串的解构赋值
const [a,b,c,d] = 'hello';
console.log(a);
console.log(b);
console.log(c);
console.log(d);
字符串因为被转换为了类数组对象,所以可以解构赋值
类数组对象都有一个length属性,可以对这个属性进行解构赋值
let {length: len} = 'hello';
console.log(len); //5
数值和布尔值的解构赋值
解构赋值时,如果等号右边的是数值和布尔值时,会先转换为对象
let {toString: S} = 123;
S === Number.prototype.toString; // true
let {toString: T} = true;
S === Boolean.prototype.toString // true
解构赋值规则
只要等号右边的值不是对象或者数组,就先将其转为对象;
undefined和null无法转为对象,所以对他们进行解构赋值时会报错
函数参数的解构赋值
待定
解构赋值的用途
1.变换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
console.log(x); //2
console.log(y); //1
2.从函数返回多个值
函数只能返回一个值,如果要返回多个值,只能将他们放在数组或对象里返回。而有了解构赋值,取出这些值就很方便啦
//返回一个数组
function example (){
return [1, 2, 3]
}
let [a, b, c] = example();
console.log(a); //1
console.log(b); //2
console.log(c); //3
// 返回一个对象
function example2 (){
return {
foo: 1,
bar: 2
}
}
let {foo, bar} = example2();
console.log(foo); //1
console.log(bar); //2
函数参数的定义
可以方便的将一组参数与变量名对应起来
//参数是一组有次序的值
function f ([x, y, z]){
console.log(x); //1
console.log(y); //2
console.log(z); //3
}
f([1, 2, 3]);
//参数是一组无次序的值
function ff ({x, y, z}){
console.log(x); //1
console.log(y); //2
console.log(z); //3
}
ff({z: 3, x: 1, y:2});
4.提取json数据的值
let jsonData = {
id: 11,
status: 'ok',
data: ['sss','aaa']
}
let {id, status, data: str} = jsonData;
console.log(id); //11
console.log(status); //'ok'
console.log(str); //['sss','aaa']
5.函数参数的默认值
function f([x = 1, y = 2]){
console.log(x,y)
x = 2;
console.log(x)
}
f([3,5]); //3,5 //2 传值的时候覆盖默认值
f([]); //1,2 //2 不传值的时候使用默认值
6.遍历map解构
let map = new Map()
.set('first', 'Hello')
.set('last', 'world');
for(let [key, value] of map){
console.log(key +'==='+ value)
}
//first === Hello
//last === world
//获取键名
for(let [key] of map){
console.log(key)
}
//first
//last
//获取键值
for(let [,value] of map){
console.log(value)
}
//Hello
//world