JavaScript 解構賦值實用指南
大家好,我是 CUGGZ,最近更新的比較慢,主要我很懶不想去轉發文章,後面準備加緊更新啦,不要取關我呀!今天來看看 ES6 解構賦值的實用技巧~
一、基本概念
爲什麼需要解構呢,先來看一個例子:
const student = {
name: 'ZhangSan',
age: 18,
scores: {
math: 19,
english: 85,
chinese: 100
}
};
function displayInfo(student) {
console.log('name:', student.name);
console.log('math:', student.scores.math);
console.log('english:', student.scores.english);
console.log('chinese:', student.scores.chinese);
}
displayInfo(student);
這樣寫也能實現預期效果,但是代碼看起來比較冗餘。並且,如果對象內部嵌套較深時,那麼對象的訪問鏈就會變得很長。雖然這並不是什麼大問題,但是使用解構賦值會讓代碼變得更簡單和易讀。
下面就來看看什麼是解構賦值。MDN 中對解構賦值的描述:
解構賦值語法是一種 Javascript 表達式。通過解構賦值, 可以將屬性值從對象 / 數組中取出, 賦值給其他變量。
實際上,結構賦值就是將複雜的結構分解爲簡單的部分。解構賦值語法可以用於變量聲明或者變量賦值。除此之外,還可以使用嵌套的解構賦值語法來處理嵌套結構。
比如,對上面例子中的對象進行解構:
function displayInfo(student) {
const { name, scores: {math, english, chinese} } = student;
console.log('name:', name);
console.log('math:', math);
console.log('english:', english);
console.log('chinese:', chinese);
}
這樣看起來是不是簡潔多了。
二、解構分類
根據 MDN 對解構賦值的定義,我們可以將解構賦值分爲兩大類:
-
對象解構
-
數組解構
下面就分別來看看這兩種解構賦值。
1. 對象的解構賦值
對象解構又稱爲對象屬性分配模式,它允許我們將對象的屬性值分配給相應的變量。它有兩種寫法:
let obj = {x: 1, y: 2, z: 3};
let {x: a, y: b, z: c} = obj;
console.log(a, b, c)
let {x, y, z} = obj;
console.log(x, y, z)
-
第一種(第 3 行)是對象解構的完整形式,對象的每個屬性都將被分配一個變量,其中冒號前面的是源對象中的屬性,冒號後面的是要賦值屬性;
-
第二種(第 5 行)是對象解構的簡寫形式,對象的屬性與要分配的屬性一致時可以使用這種形式。
如果需要給已有變量賦值,就需要額外注意了:
let obj = {x: 1, y: 2, z: 3};
let x = 0, y = 0, z = 0;
({x, y, z} = obj)
console.log(x, y, z)
這裏需要注意,需要將賦值表達式使用括號括起來,如果省略,解構對象將被視爲一個塊語句,而塊語句是不能放在賦值表達式左側的。
當使用解構賦值時,可以給變量傳遞一個默認值:
const person = {
name: 'ZhangSan',
height: 180
};
const { name, height, age = 25 } = person;
console.log(name, height, age);
這裏我們給 age 分配了一個默認值,當對源對象上不存在 age 屬性時,age 就會被賦上默認值 25,而不是 undefined。
如果分配的對象屬性爲 undefined,那麼就會使用默認值:
const {x = 2} = {x: undefined};
console.log(x); // 2
2. 數組的解構賦值
在使用數組解構時,實際上會使用迭代器將所需要的值與結構源分開。因此,我們可以對可迭代值使用數組結構,包括字符串、數組、集合、函數映射、DOM 元素。我們還可以將解構賦值與擴展運算符結合使用。
(1)字符串
let message = 'Hello';
let [a, b] = message;
let [x, y, ...z] = message;
console.log(a, b); // H e
console.log(x, y, z); // H e ['l', 'l', 'o']
(2)數組
let numbers = [1, 2, 3];
let [x, y, z] = numbers;
console.log(x, y, z); // 1 2 3
(3)集合
let set = new Set().add('foo').add('bar');
let [a, b] = set;
console.log(a, b); // foo bar
(4)Map
let map = new Map().set('a', 1).set('b', 2);
let [x, y] = map;
console.log(x, y); // ["a", 1] ["b", 2]
在數組的解構中,存儲變量的數組中的每個變量都會映射到解構數組上相同索引處的相應項。
如果解構中某一項不需要,可以使用逗號操作符進行分隔:
const rgb = [200, 255, 100];
const [,, blue] = rgb;
console.log(blue); // 100
與對象解構一樣,可以使用數組解構爲局部變量設置默認值:
const rgb = [200];
const [red = 255, green, blue = 255] = rgb;
console.log(`R: ${red}, G: ${green}, B: ${blue}`);
如果變量已經存在,就可以這麼寫:
let red = 100, green = 200, blue = 50;
const rgb = [200, 255, 100];
[red, green] = rgb;
console.log(`R: ${red}, G: ${green}, B: ${blue}`);
與對象解構不同的是,這裏不需要括號將數組括起來。
如果給變量分配的值是 undefined,那麼就會使用默認值:
const [x = 1] = [undefined];
console.log(x); // 1
這裏的默認值並不一定是一個固定值,它可以是一個計算屬性:
function foo() {
return 1;
}
let obj1 = {x: 2};
let obj2 = {x: undefined};
let {x=foo()} = obj1;
console.log(x); // 2
let {x=foo()} = obj2;
console.log(x); // 1
如果我們想將數組中的一些元素分配給變量,而將數組中的其餘項分配給特定的變量就可以這樣做:
let [greeting,...intro] = ["Hello", "I" , "am", "CUGGZ"];
console.log(greeting); // "Hello"
console.log(intro); // ["I", "am", "CUGGZ"]
三、嵌套解構
上面我們說的解構的只是普通的數組和對象。實際上,解構賦值可以用於嵌套數組和嵌套對象。比如,文章最開始的例子中,就是解構的嵌套對象:
const student = {
name: 'ZhangSan',
age: 18,
scores: {
math: 19,
english: 85,
chinese: 100
}
};
const { name, scores: {math, english, chinese} } = student;
再來看一個嵌套數組解構的例子:
let numbers = [1, [2, 3, 4], 5];
let [a, [b, c, d], e] = numbers;
console.log(a, b, c, d, e); // 1 2 3 4 5
四、使用技巧
1. 函數解構
(1)解構函數參數
可以對函數參數使用解構賦值:
function foo([a, b]) {
console.log(a + b);
}
foo([1, 2]); // 3
function bar({x, y}) {
console.log(x, y);
}
foo({x: 1, y: 2}); // 1 2
可以對函數返回值使用解構賦值:
function getStudentInfo() {
return {
name: 'ZhangSan',
age: 18,
scores: {
math: 19,
english: 85,
chinese: 100
}
};
}
const { name, scores: {math, english, chinese} } = getStudentInfo();
console.log(name, math, english, chinese);
2. 循環中的解構
當我們需要循環中的對象鍵值時,也可以使用對象解構:
const students = [
{
'name': 'ZhangSan',
'grade': 80
},
{
'name': 'LiSi',
'grade': 75
},
{
'name': 'WangWu',
'grade': 95
}
];
for(let {name, grade} of students){
console.log(name, grade);
}
3. 動態屬性解構
很多時候我們不知道對象屬性的 key,只有運行時才知道。比如有一個方法 getStudentInfo,它以一個 key 爲參數,並返回相應的屬性值:
getStudentInfo('name');
getStudentInfo('age');
這裏傳遞給 getStudentInfo 方法的參數是動態的,因此可以這樣寫:
const getStudentInfo = key => {
const {[key]: value} = student;
return value;
}
需要注意,包裹 key 的方括號不能少,否則會出現 undefined 值。
4. 交換變量
數組結構一個很實用的功能就是實現交換局部變量。通常,我們會藉助臨時變量來實現變量的交換:
let width = 300;
let height = 400;
let temp = width;
width = height;
height = temp;
console.log(width, height)
如果使用數組的解構賦值,就會變得很簡單:
let width = 300;
let height = 400;
[width, height] = [height, width];
console.log(width, height)
5. 數組拷貝
可以使用解構賦值和 rest 運算符來實現數組的拷貝:
const rgb = [200, 255, 100];
const [...newRgb] = rgb;
// 等同於 const newRgb = [...rgb]
console.log(newRgb)
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/D-WacGCqqeNIgasxNbXfHA