一. 基本概念
ES6(ES2015)的發布,給JavaScript 提供了一種更方便快捷的方式來處理對象或數組的屬性。該機制稱為Destructuring(也稱為解構賦值)。
下面就來看看什么是解構賦值。MDN 中對解構賦值的描述:
解構賦值語法是一種 Javascript 表達式。通過解構賦值, 可以將屬性值從對象/數組中取出,賦值給其他變
量。
實際上,結構賦值就是將復雜的結構分解為簡單的部分。解構賦值語法可以用於變量聲明或者變量賦值。除此之外,還可以使用嵌套的解構賦值語法來處理嵌套結構。
二. 解構分類
根據MDN對解構賦值的定義,我們可以將解構賦值分為兩大類:
- 對象解構
- 數組解構
三. 對象的解構賦值
1.對象中獲取值
對象解構又稱為對象屬性分配模式,它允許我們將對象的屬性值分配給相應的變量。它有兩種寫法:
let obj = {x: 1, y: 2, z: 3}; let {x, y, z} = obj; console.log(x, y, z) let {x: a, y: b, z: c} = obj; // 別名 console.log(a, b, c)
第1種 是對象解構的簡寫形式,對象的屬性與要分配的屬性一致時可以使用這種形式;
第2種 是對象解構的完整形式,對象的每個屬性都將被分配一個變量,其中冒號前面的是源對象中的屬性,冒號后面的是要賦值屬性(其實類似於是用別名)。
2. 默認值與新變量
當然我們在日常開發的過程中,可能會遇到很多極端的情況,例如后端傳過來的對象,可能會缺失某些字段:
const person = { name: 'ZhangSan', height: 180, age: undefined, // 只有undefined可以 null 0 都不行 }; const { name, height, age = 25, gender = '男'} = person; console.log(name, height, age, gender); // ZhangSan 180 25 男
這里我們給age分配了一個默認值,當對源對象上不存在age屬性時,age就會被賦上默認值25,而不是undefined。
如果分配的對象屬性為undefined,那么就會使用默認值
const {x = 2} = {x: undefined}; console.log(x); // 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]
5.Tips
在數組的解構中,存儲變量的數組中的每個變量都會映射到解構數組上相同索引處的相應項。
如果解構中某一項不需要,可以使用逗號操作符進行分隔:
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"]
五. 嵌套解構
實際上,解構賦值可以用於嵌套數組和嵌套對象
1.解構嵌套對象
const student = { name: 'ZhangSan', age: 18, scores: { math: 19, english: 85, chinese: 100 } }; const { name, scores: {math, english, chinese} } = student;
2.解構嵌套數組
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
(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 User= [ { 'name': '路人甲', 'age': 16 }, { 'name': '路人乙', 'age': 18 }, { 'name': '路人丙', 'age': 20 } ];
您可以使用for-of循環遍歷User對象,然后使用對象解構賦值語法來檢索詳細信息。
for(let {name, age} of User) { console.log(`${name} 今年${age}歲!!!`); } // 路人甲 今年16歲!!! // 路人乙 今年18歲!!! // 路人丙 今年20歲!!!
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)