原文:Dmitri Pavlutin翻譯:瘋狂的技術宅
原文:https://dmitripavlutin.com/5-...
未經允許嚴禁轉載
如果你查看我的常規 JavaScript 代碼,會看到到處都有解構。
讀取對象屬性和訪問數組項是常見的操作。結構使這些操作變得更加輕鬆和簡潔。
在本文中,除了基本用法之外,我還將會介紹在 JavaScript 中 5 種有趣的解構用法。
1. 交換變量
通常交換兩個變量的方法需要一個附加的臨時變量。讓我們看一個簡單的場景:
let a = 1;
let b = 2;
let temp;
temp = a;
a = b;
b = temp;
a; // => 2
b; // => 1
temp
是保存 a
的值的臨時變量。然後,爲 a
分配 b
的值,最後爲 b
分配 temp
的值。
解構分配使變量交換變得簡單,不需要任何臨時變量:
let a = 1;
let b = 2;
[a, b] = [b, a];
a; // => 2
b; // => 1
[a,b] = [b,a]
是一個破壞性分配。在右側,創建一個數組 [b,a]
,即 [2,1]
。數組的第一項 2
分配給 a
,第二項 1
分配給 b
。
儘管仍會創建臨時數組,但使用解構分配交換變量更爲簡潔。
這不是極限。你可以同時交換兩個以上的變量。讓我們嘗試一下:
let zero = 2;
let one = 1;
let two = 0;
[zero, one, two] = [two, one, zero];
zero; // => 0
one; // => 1
two; // => 2
你可以根據需要交換任意多個變量!雖然交換兩個變量是最常見的操作。
2. 訪問數組項
假設你有一系列可能爲空的項目。你要訪問數組的第一、第二或第 n 個項目,但是如果該項目不存在,請獲取默認值。
通常你會用到數組的 length 屬性:
const colors = [];
let firstColor = 'white';
if (colors.length > 0) {
firstColor = colors[0];
}
firstColor; // => 'white'
幸運的是,數組解構可以幫助你實現更短的操作代碼:
const colors = [];
const [firstColor = 'white'] = colors;
firstColor; // => 'white'
const [firstColor ='white'] = colors
解構將 colors
數組的第一個元素分配給 firstColor
變量。如果數組在索引 0
處沒有任何元素,則將分配默認值 white
。
但是這有更多的靈活性。如果你只想訪問第二個元素,也可以這樣:
const colors = [];
const [, secondColor = 'black'] = colors;
secondColor; // => 'black'
注意結構左側的逗號:這意味着第一個元素將被忽略。從 color
數組中爲索引爲 1
的元素分配了 secondColor
。
3.不變的操作
當我開始用 React 以及後來的 Redux 時,被迫編寫尊重不變性的代碼。儘管一開始遇到了一些困難,但後來我看到了它的好處:單向數據流更容易處理。
不變性禁止更改對象。幸運的是,解構可以幫你輕鬆地以不變的方式完成某些操作。
結合使用 ...
rest 操作符可以從數組的開頭刪除元素:
const numbers = [1, 2, 3];
const [, ...fooNumbers] = numbers;
fooNumbers; // => [2, 3]
numbers; // => [1, 2, 3]
解構 [, ...fooNumbers] = numbers
將創建一個新的數組 fooNumbers
,其中包含來自 numbers
的項目,除了第一項。
numbers
數組不會發生變異,從而使操作保持不變。
你可以以不變的方式從對象中刪除屬性。讓我們嘗試從對象 big
中刪除 foo
屬性:
const big = {
foo: 'value Foo',
bar: 'value Bar'
};
const { foo, ...small } = big;
small; // => { bar: 'value Bar' }
big; // => { foo: 'value Foo', bar: 'value Bar' }
解構與 object rest operator 結合使用可創建一個具有 big
所有屬性的新對象 small
,唯獨不包含 foo
。
4. 解構可迭代對象
在前面的章節中,我們將解構應用於數組。但是你可以解構實現了可迭代協議的任何對象。
許多原生原始類型和對象都是可迭代的:數組、字符串、類型化數組、集合和映射。
例如,你可以將字符串分解爲字符:
const str = 'cheese';
const [firstChar = ''] = str;
firstChar; // => 'c'
不僅限於原生類型,也可以通過實現可迭代協議來自定義解構邏輯。
movies
擁有電影對象的列表。解構 movies
時,最好將電影標題作爲字符串。讓我們實現一個自定義迭代器:
const movies = {
list: [
{ title: 'Heat' },
{ title: 'Interstellar' }
],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.list.length) {
const value = this.list[index++].title;
return { value, done: false };
}
return { done: true };
}
};
}
};
const [firstMovieTitle] = movies;
console.log(firstMovieTitle); // => 'Heat'
movies
對象通過定義 Symbol.iterator
方法來實現可迭代的協議。迭代器遍歷電影的標題。
遵循可迭代協議,可以將 movies
對象結構爲標題,特別是通過讀取第一部電影的標題: const [firstMovieTitle] = movies
。
在使用迭代器進行解構時,只有天空纔是對你的限制。
5. 解構動態屬性
以我的經驗,通過屬性對對象進行解構比對數組進行解構更爲常見。
對象的解構看起來非常簡單:
const movie = { title: 'Heat' };
const { title } = movie;
title; // => 'Heat'
const {title} = movie
創建一個變量 title
併爲其屬性 movie.title
賦值。
當初讀到有關對象解構的文章時,我驚訝於不必靜態地知道屬性名稱。你可以用動態屬性名稱來解構對象!
要了解動態解構的工作原理,我們編寫一個函數:
function greet(obj, nameProp) {
const { [nameProp]: name = 'Unknown' } = obj;
return `Hello, ${name}!`;
}
greet({ name: 'Batman' }, 'name'); // => 'Hello, Batman!'
greet({ }, 'name'); // => 'Hello, Unknown!'
使用兩個參數調用 greet()
函數:對象和屬性名稱。
在 greet()
內部,解構賦值 const {[nameProp]:name ='Unknown'} = obj
使用方括號 [nameProp]
讀取動態屬性名稱。變量 name
接收動態屬性值。
更妙的是如果該屬性不存在,則可以指定默認值 'Unknown'
。
六. 結論
如果要訪問對象屬性和數組項,則解構效果很好。
除了基本用法外,數組解構還可以方便地交換變量、訪問數組項、執行一些不可變的操作。
JavaScript 提供了更大的可能性,因爲你可以用迭代器自定義解構邏輯。
你知道還有哪些關於解構有趣的應用?在下面寫評論!
本文首發微信公衆號:前端先鋒
歡迎掃描二維碼關注公衆號,每天都給你推送新鮮的前端技術文章
歡迎繼續閱讀本專欄其它高贊文章:
- 深入理解Shadow DOM v1
- 一步步教你用 WebVR 實現虛擬現實遊戲
- 13個幫你提高開發效率的現代CSS框架
- 快速上手BootstrapVue
- JavaScript引擎是如何工作的?從調用棧到Promise你需要知道的一切
- WebSocket實戰:在 Node 和 React 之間進行實時通信
- 關於 Git 的 20 個面試題
- 深入解析 Node.js 的 console.log
- Node.js 究竟是什麼?
- 30分鐘用Node.js構建一個API服務器
- Javascript的對象拷貝
- 程序員30歲前月薪達不到30K,該何去何從
- 14個最好的 JavaScript 數據可視化庫
- 8 個給前端的頂級 VS Code 擴展插件
- Node.js 多線程完全指南
- 把HTML轉成PDF的4個方案及實現