JavaScript解構賦值的實用技巧指南
目錄
- 一、基本概念
- 二、解構分類
- 1. 物件的解構賦值
- 2. 陣列的解構賦值
- (1)字串
- (2)陣列
- (3)集合
- (4)Map
- 三、巢狀解構
- 四、使用技巧
- 1. 函式解構
- (1)解構函式引數
- 2. 迴圈中的解構
- 3. 動態屬性解構
- 4. 交換變數
- 5. 陣列拷貝
- 四、解構賦值注意點
- 總結
一、基本概念
為什麼需要解構呢,先來看一個例子:
const student = { name: 'ZhangSan',age: 18,scores: { math: 19,english: 85,chinese: 100 } }; function displayInfo(student) { console.http://www.cppcns.comlog('name:',student.name); console.log('math:',student.scores.math); console.log('english:',student.scores.english); console.log('chinese:',student.scores.chinese); } displayInfo(student);
這樣寫也能實現預期效果,但是程式碼看起來比較冗餘。並且,如果物件內部巢狀較深時,那麼物件的訪問鏈就會變得很長。雖然這並不是什麼大問題,但是使用解構賦值會讓程式碼變得更簡單和易讀。
下面就來看看什麼是解構賦值。MDN 中對解構賦值的描述:
解構賦值語法是一種 表示式。通過解構賦值,可以將屬性值從物件/陣列中取出,賦值給其他變數。
實際上,結構賦值就是將複雜的結構分解為簡單的部分。解構賦值語法可以用於變數宣告或者變數賦值。除此之外,還可以使用巢狀的解構賦值語法來處理巢狀結構。
比如,對上面例子中的物件進行解構:
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,z)
- 第一種(第3行)是物件解構的完整形式,物件的每個屬性都將被分配一個變數,其中冒號前面的是源物件中的屬性,冒號後面的是要賦值屬性;
- 第二種(第5行)是物件解構的簡寫形式,物件的屬性與要分配的屬性一致時可以使用這種形式。
如果需要給已有變數賦值,就需要額外注意了:
let obj = {x: 1,z: 3}; let x = 0,y = 0,z = 0; ({x,www.cppcns.com z} = obj) console.log(x,z)
這裡需要注意,需要將賦值表示式使用括號括起來,如果省略,解構物件將被視為一個塊語句,而塊語句時不能放在賦值表示式左側的。
當使用解構賦值時,可以給變數傳遞一個預設值:
const person = { name: 'ZhangSan',height: 180 }; const { name,height,age = 25 } = person; console.log(name,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,...z] = message; console.log(a,b); // H e console.log(x,z); // H e ['l','l','o']
(2)陣列
let numbers = [1,2,3]; let [x,z] = numbers; console.log(x,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: $oWMYUvj{red},G: ${green},B: ${blue}`);
如果變數已經存在,就可以這麼寫:
let red = 100,green = 200,blue = 50; const rgb = [200,100]; [red,green] = rgb; console.log(`R: ${red},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","CUGGZ"]
三、巢狀解構
上面我們說的解構的知識普通的陣列和物件。實際上,解構賦值可以用於巢狀陣列和巢狀物件。比如,文章最開始的例子中,就是解構的巢狀物件:
const student = { name: 'ZhangSan',chinese: 100 } }; const { name,chinese} } = student;
再來看一個巢狀陣列解構的例子:
let numbers = [1,[2,3,4],5]; let [a,[b,c,d],e] = numbers; console.log(a,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',scores: { math: 19,chinese: 100 } }; } const { name,chinese} } = getStudentInfo(); console.log(name,math,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)
如果使用陣列的解構賦值,就會變得很簡http://www.cppcns.com單:
let width = 300; let height = 400; [width,height] = [height,width]; console.log(width,height)
5. 陣列拷貝
可以使用解構賦值和rest運算子來實現陣列的拷貝:
const rgb = [200,100]; const [...newRgb] = rgb; // 等同於 const newRgb = [...rgb] console.log(newRgb)
四、解構賦值注意點
為了防止從陣列中取出一個值為undefined的物件,可以在表示式左邊的陣列中為任意物件預設預設值。
意思是:定義這個變數或者變數的值設定為undefined的時候,而null、''、false在變數解析的過程中都是有值得情況,所以我們預設賦值會不成功。
示例如下:
const {a = '1',b = '2',c = '3',d = '4',e = '5'} = {a: 'a',b: null,c: undefined,d: false,e: ''} console.log(a); //a console.log(b); //null console.log(c); //3 console.log(d); //false console.log(e); // ""
如果只是根據屬性的存在與否來繫結預設值的時候,可以使用解構賦值。
總結
到此這篇關於Script解構賦值的文章就介紹到這了,更多相關JavaScript解構賦值內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!