解构赋值
es6允许按照一定的模式,从对象和数组中提取值,对变量进行赋值,这被称为解构。
这种写法属于匹配模式,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
解构赋值:解析数据源,然后按照数据模型进行取值 ,再赋值给变量(实质上就是声明变量的高级写法 )
语法: 变量修饰符 数据模型=数据源
过程:解构:按照数据模型取出数据源中的数据
赋值:然后赋值给模型变量
数组的解构赋值
let [x, y, z] = [1, 2, 3];
console.log(x, y, z); //1 2 3
let [a, [[b], c]] = [1, [[2], 3]];
console.log(a, b, c); //1 2 3
let [, , third] = [1, 2, 3];
console.log(third); //3
let [aa, , cc] = [1, 2, 3];
console.log(aa,cc); //1 3
… 剩余运算符,搭配的变量是一个数组,会将剩下的数放在数组中
只能放在末尾
let [head, ...tail] = [1, 2, 3];
console.log(head, tail); //1 [2,3]
如果解构赋值不完全,变量的值就为undefined
let [x1, x2, x3] = [1];
console.log(x1, x2, x3); //1 undefined undefined
不完全解构
// 1.赋值大于变量
let [y1, y2] = [1, 2, 3];
console.log(y1, y2); //1 2
// 2.赋值小于变量
let [z1, z2, z3] = [1, 2];
console.log(z1, z2, z3); //1 2 undefined
设置默认值,当值为undefined(===)时触发该变量的默认值
let [a1 = 0, a2 = 0, a3=0] = [1, null];
console.log(a1, a2, a3); //1 null 0
默认值如果是一个表达式,那么这个表达式是惰性求值,只有在用到时才会求值
function f() {
console.log('aaa');
}
let [xx = f()] = [1];
console.log(xx) //1
let [yy = f()] = [];
console.log(yy) //undefined f()返回值为undefined
对象的解构赋值
变量名和属性名一致时,可简写
对象的解构赋值的内部机制是先找同名的属性,然后再将对应的值赋值给变量。
let { a1, a2, a3 } = { a2: 1, a1: 2, a3: 3 };
// {a1:a1,a2:a2,a3:a3}
console.log(a1, a2, a3); //2 1 3
如果解构失败,变量的值是undefined
let { y1: z1, y2: z2 } = { y1: 1, z2: 2 }
console.log(z1, z2); //1 undefined
对象的解构赋值将现有对象的方法赋值到变量
let { log } = console;
//let {log:log} = console {log:function}
log(999); //999
let { sin, cos, PI } = Math;
console.log(PI); //3.141592653589793
对象的解构赋值也可以嵌套
let obj1 = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p: [x, y] } = obj1;
console.log(x,y); //Hello { y: 'World' }
let obj1 = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p, p: [x, { y }] } = obj1;
console.log(p, x, y); //['Hello',{ y: 'World' }] 'Hello' 'World'
const node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
let { loc, loc: { start }, loc: { line } } = node;
console.log(loc,start,line); //{start: {line: 1,column: 5}} {line: 1,column: 5} undefined
对象的解构赋值可以取到继承的属性
let obj2 = {
name:"aaa"
}
let obj3 = {
age:18
}
obj2.__proto__ = obj3;
let {age} = obj2;
console.log(age); //18
对象的解构赋值也可以设置默认值
let {v1 = 0,v2} = {v2:1,v3:2};
console.log(v1,v2); //0 1
let {c1:d1=0,c2:d2} = {c2:4}
console.log(d1,d2); //0 4
其他类型的解构赋值
字符串的解构赋值
//let obj = new String("str");
//console.log(obj);
let [x, y, z] = "str";
console.log(x, y, z); //s t r
let { 0: x1, 1: y1, 2: z1 } = "str";
console.log(x1, y1, z1); //s t r
数字和布尔的解构赋值
let {aa} = 1; //1转为对象是一个空对象
let {bb} = true; //true转为对象是一个空
console.log(aa); //undefined
console.log(bb); //undefined
undefined和null的解构赋值
undefined和null无法转为对象,它们的解构赋值都会报错。
解构赋值的规则:只要等号右边的值不是对象或数组,就先将其转为对象。
函数参数的解构赋值
function fn([x, y]){
//[x, y] = [1, 2]
//x=1,y=2
return x + y;
}
fn([1, 2]); // 3
函数参数的解构也可以使用默认值。
function move({ x = 0, y = 0 } = {}) {
//{ x:x = 0, y:y = 0 } = {}
//当x,y匹配值为undefined,则触发默认值
return [x, y];
}
move({ x: 3, y: 8 });//[3,8]
move({ x: 3 });//[3,0]
move({});//[0,0]
move();//[0,0]
function move({x, y} = { x: 0, y: 0 }) {
//{x:x, y:y} = { x: 0, y: 0 }
return [x, y];
}
move({ x: 3, y: 8 });//[3.8]
move({ x: 3 });//[3,undefined]
move({});//[undefined,undefined]
move();//[0,0]