解构赋值
解构赋值是什么
解构赋值语法是一种 Javascript 表达式,通过它能将属性或值从对象或数组中取出来,并赋给其它变量。现在有一个普通对象如下。
let obj = {
id: 1,
username: 'ostuthere',
gender: 'female',
age: 20
}
在解构赋值出现之前,我们通常定义一个变量来接收对象的属性。
let id = obj.id;
let username = obj.username;
let gender = obj.gender;
let age = obj.age;
console.log(id, username, gender, age); // 1 ostuthere female 20
在 ES6 的解构赋值语法出现之后,代码变得更为简洁并且通俗易懂,具体如下。
let {id, username, gender, age} = obj;
console.log(id, username, gender, age); // 1 ostuthere female 20
解构赋值怎么用
对象字面量和数组字面量提供了一种简单的定义一个特定的数据组的方法。解构赋值与字面量的语法相同,不同的是在表达式左边定义了要从对象或者数组中取出什么变量。假设现在有一个稀疏数组和一个比较复杂的嵌套对象,对这个数组和对象分别进行解构赋值操作看看是什么结果。
let arr = [1, , 3, 4, , 6];
let obj = {
id: 1,
username: 'ostuthere',
gender: 'female',
age: 20,
family: {
mother: 'Mother',
father: 'Father',
brother: ['Brother1', 'Brother2']
}
}
基本用法
一般来说,解构赋值都会在声明变量的同时进行赋值。
let [one] = arr;
console.log(one); // 1
let {id, username, gender, age} = obj;
console.log(id, username, gender, age); // 1 ostuthere female 20
先声明之后再对变量进行赋值也是可以的。
let one;
[one] = arr;
console.log(one); // 1
let id, username, gender, age;
({id, username, gender, age} = obj);
console.log(id, username, gender, age); // 1 ostuthere female 20
注意
:使用对象字面量无声明赋值时一定要用圆括号把赋值语句包起来,否则左边的花括号部分会被认为是一个块,而不是对象字面量;而且在圆括号之前一定要有分号,否则会被当做前面代码的函数执行。
解构对象时还可以将提取出来的变量赋值给一个与属性名不同的新变量。
let p1, p2, p3, p4;
({id: p1, username: p2, gender: p3, age: p4} = obj);
console.log(p1, p2, p3, p4); // 1 ostuthere female 20
默认值
在解构赋值时可以给变量设置一个默认值。若取出的值为 undefined
,变量就会采用默认值。
let [one, two = 22] = arr;
console.log(one, two); // 1 22
let {username = 'user', gender = 'female', age = 18, o: other= 'none'} = obj;
console.log(username, gender, age, other); // ostuthere female 20 none
忽略某些值
对数组进行解构时可以选择只解构出自己需要的某些值,在目标值之前的值直接用逗号表示忽略。
let [, , three] = arr;
console.log(three); // 3
结合剩余操作符
解构时可以利用剩余操作符将没有解构的部分作为一个数组或者对象赋值给一个变量,注意剩余操作符必须作用在最后一个变量,如果在它的右边还有逗号则会报错。
let [one, two=22, three, ...rest1] = arr;
console.log(rest1); // [4, undifined, 6]
let {username = 'user', gender = 'female', age = 18, ...rest2} = obj;
console.log(rest2);
// {id: 1, family: {mother: 'Mother',father: 'Father',brother: [ 'Brother1', 'Brother2' ]}}
解构对象时会查找原型链
在 obj 对象的原型上添加一个属性 a,解构时给 a 赋默认值,看输出的是默认值还是原型上的属性值。
obj.__proto__.a = 'proto';
let {a = 'none', b = 'none'} = obj;
console.log(a); // proto none
由上示例可知,如果解构的属性不存在于对象本身,那么会沿着对象的原型链进行查找,直到找到目标属性或原型链的最后(会返回 undefined)。
解构赋值可以做什么
交换变量
解构赋值出现之前,如果要交换两个变量,通常都会选择引入一个临时变量来辅助。
let a = 1, b = 2, temp;
console.log(a, b); // 1 2
temp = a;
a = b;
b = temp;
console.log(a, b); // 2 1
利用解构赋值只需要一行代码就能搞定,且不需要临时变量。
let a = 1, b = 2;
console.log(a, b); // 1 2
[b, a] = [a, b];
console.log(a, b); // 2 1
结合for…of进行遍历
for…of 可以遍历可迭代对象,还可以结合解构赋值快捷地获取我们需要的变量。
let obj = [
{
id: 1,
name: 'user1',
age: 18,
msg: 'hello'
},
{
id: 2,
name: 'user2',
age: 20,
msg: 'nice'
},
]
for(let {name, age, msg} of obj1) {
console.log("name=" + name + " age=" + age + " msg=" + msg);
// name=user1 age=18 msg=hello
// name=user2 age=20 msg=nice
}
解析作为函数返回值的数组
函数返回一个数组的情况很常见,解构赋值能让我们更便捷地处理数组返回值。
function f() {
return [1, 2];
}
let a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
解析作为函数实参的对象
在处理函数参数时,常常会遇到入参是对象类型的情况。ES6 之前如果要处理对象参数,需要多行代码一个个地提取对象属性。
function showInfo(options) {
options = options === undefined ? {} : options;
let username = options.username === undefined ? 'user' : options.username;
let gender = options.gender === undefined ? 'female' : options.gender;
let age = options.age === undefined ? 18 : options.age;
let msg = options.msg === undefined ? 'hello' : options.msg;
console.log(username, gender, age, msg);
}
let obj = {
username: 'user1',
gender: 'male',
age: 23,
msg: 'lalalala'
}
showInfo(obj); // user1 male 23 lalalala
showInfo(); // user female 18 hello
但是通过解构赋值可以一行代码解决。
function showInfo({username='user', gender='female', age=18, msg='hello'} = {}) {
console.log(username, gender, age, msg);
}