ES6——变量的解构赋值

本文介绍了ES6的解构赋值,包括数组、对象、字符串、数值和布尔值的解构赋值,以及函数参数的解构赋值。阐述了不同类型解构赋值的规则、默认值设定等,还提及解构赋值在交换变量值、从函数返回多值等方面的用途。

ES6 允许按照一定模式,从数组对象中提取值,对变量进行赋值,这被称为解构

let [a, b] = [1, 2];
let {c, d} = {c: 3, d: 4};

console.log(a);			//1
console.log(b);			//2
console.log(c);			//3
console.log(d);			//4

数组的解构赋值

let [a, b] = [1, 2];

console.log(a);			//1
console.log(b);			//2

这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

let [a, [[b], c]] = [1, [[2], 3]];
console.log(a);			//1
console.log(b);			//2
console.log(c);			//3

let [, , d] = [4, 5, 6];
console.log(d);			//6

let [e, ...f] = [7, 8, 9];
console.log(e);			//7
console.log(f);			//[8, 9]

如果解构不成功,变量的值就等于undefined

let [a] = [];
console.log(a);			//undefined

let [b, c] = [1];
console.log(b);			//1
console.log(c);			//undefined

let [d, e, ...f] = [2];
console.log(d);			//2
console.log(e);			//undefined
console.log(f);			//[]

另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

let [a, b] = [1, 2, 3];
console.log(a);			//1
console.log(b);			//2

let [c, [d], e] = [4, [5, 6], 7];
console.log(c);			//4
console.log(d);			//5
console.log(e);			//7

如果等号的右边不是可遍历的结构,那么将会报错。

// 报错
let [a] = 1;
let [b] = false;
let [c] = NaN;
let [d] = undefined;
let [e] = null;
let [f] = {};

解构赋值允许指定默认值。

let [a = 1] = [];

console.log(a);			//1

只有当一个数组成员严格等于(===undefined,默认值才会生效。

let [a = 1] = [undefined];
let [b = 2] = [null];

console.log(a);			//1
console.log(b);			//null

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

let [a = 1, b = a] = [];
console.log(a);			//1
console.log(b);			//1

//报错
let [c = d, d = 1] = [];

对象的解构赋值

let {a, b} = {a: 1, b: 2};

console.log(a);			//1
console.log(b);			//2

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的变量的取值由它的位置决定;而对象的属性没有次序变量必须与属性同名,才能取到正确的值。

let {b, a} = {a: 1, b: 2};
console.log(a);			//1
console.log(b);			//2

如果没有对应的同名属性则解构失败,变量的值等于undefined

let {a} = {b: 1, c: 2};
console.log(a);			//undefined

如果变量名与属性名不一致,必须写成下面这样。

let {a: b} = {a: 1};

console.log(b);			//1

与数组一样,解构也可以用于嵌套结构的对象。

let obj = {
	arr: [
	    1,
		{b: 2}
	]
};
let {arr: [a, {b}]} = obj;

console.log(a);			//1
console.log(b);			//2

注意,这时arr是模式,不是变量,因此不会被赋值。如果arr也要作为变量赋值,可以写成下面这样。

let obj = {
	arr: [
	    1,
		{b: 2}
	]
};
let {arr, arr: [a, {b}]} = obj;

console.log(a);			//1
console.log(b);			//2
console.log(arr);		//[1, {b: 2}]

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。

//报错
let {arr: {a}} = {a: 1};		

对象的解构赋值可以取到继承的属性。

let obj1 = {};
let obj2 = {a: 1};
obj1.__proto__ = obj2;

let {a} = obj1;
console.log(a);			//1

对象的解构也可以指定默认值。默认值生效的条件是,对象的属性值严格等于(===undefined

let {a = 1} = {};
console.log(a);			//1

let {b = 2} = {b: null};
console.log(b);			//null

如果要将一个已经声明的变量用于解构赋值,必须非常小心。

let a;
{a} = {a: 1};			//报错

上面代码的写法会报错,因为 JavaScript 引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

let a;
({a} = {a: 1});			//不报错
console.log(a);			//1

上面代码将整个解构赋值语句,放在一个圆括号里面,就可以正确执行。

字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

let [a, b, c, d, e] = "hello";
console.log(a);			//h
console.log(b);			//e
console.log(c);			//l
console.log(d);			//l
console.log(e);			//o

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length} = "hello";
console.log(length);	//5

数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

let {toString: a} = 123;
console.log(a === Number.prototype.toString);			//true

let {toString: b} = true;
console.log(b === Boolean.prototype.toString);			//true

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。
解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefinednull无法转为对象,所以对它们进行解构赋值,都会报错。

let {a} = undefined;	//报错
let {b} = null;			//报错

函数参数的解构赋值

函数的参数也可以使用解构赋值。

function fun([a, b]){
	console.log(a + b);
}
fun([1, 2]);			//3

函数参数的解构也可以使用默认值。

function fun({a = 1, b = 2} = {}){
	return [a, b];
}

fun({a: 3, b: 4});			//[3, 4]
fun({a: 3});				//[3, 2]
fun();					//[1, 2]

注意,下面的写法会得到不一样的结果。

function fun({a, b} = {a: 1, b: 2}){
	return [a, b];
}

fun({a: 3, b: 4});			//[3, 4]
fun({a: 3});				//[3, undefined]
fun({});					//[undefined, undefined]
fun();						//[1, 2]

用途

交换变量的值。

let a = 1,
b = 2;
[a, b] = [b, a];

console.log(a);			//2
console.log(b);			//1

从函数返回多个值。

//返回一个数组
function fun(){
	return [1, 2, 3];
}
let [a, b, c] = fun();

console.log(a);			//1
console.log(b);			//2
console.log(c);			//3

//返回一个对象
function fun(){
	return {
		a: 1,
		b: 2
	};
}
let {a, b} = fun();

console.log(a);			//1
console.log(b);			//2

将一组参数与变量名对应起来。

//参数是一组有次序的值
function fun([a, b, c]){
	console.log(a + b + c);
}

fun([1, 2, 3]);					//6

//参数是一组无次序的值
function fun({a, b, c}){
	console.log(a + b + c);
}

fun({c: 3, b: 2, a: 1});		//6

指定函数参数的默认值。

function fun({a = 0, b = 0, c = 0} = {}){
	console.log(a + b + c);
}

fun({a:1});						//1
fun({a:1, b: 2});				//3
fun({});						//0
fun();							//0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值