您好,登錄后才能下訂單哦!
前言
原文標題:5 Interesting Uses of JavaScript Destructuring
原文鏈接:dmitripavlutin.com/5-interesti…
定期回顧我寫的JS代碼,我發現解構運算無處不在。
獲取對象的屬性和訪問數組內容是都是很常用的操作。而解構運算使得這些操作變得非常簡單明了。
在這篇文章中,我將會講解JS解構不同于常見用法的五種使用技巧。
1. 交換變量
常見的交互兩個變量值的方法都需要借助一個額外的變量,看一個簡單的例子:
let a = 1; let b = 2; let temp; temp = a; a = b; b = temp; a; // => 2 b; // => 1
temp是一個臨時變量,在例子中存儲了變量a的值,b的值賦給了a,最后把temp的值賦給了b。
解構運算使得交換變量的值變得非常簡單,不需要借助第三個臨時變量:
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. 訪問數組
有一個數組,這個數組有可能是空的。有一種需求是訪問任意位置數組元素,如果這個位置為空,則返回一個默認值。
通常情況下有的人可能會使用數組的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的位置上沒有任何元素(注:為undefined時即認為為空),white將作為默認值賦值給firstColor。
數組解構是非常靈活的,如果你只想訪問數組的第二個元素,方法如下所示:
const colors = []; const [, secondColor = "black"] = colors; secondColor; //=> "black"
在解構表達式的左邊寫一個逗號:意味著數組的第一個元素被忽略掉。colors數組下標為1的元素被解構賦值給了變量secondColor。
3. 不可變操作
從我開始使用React,到后來的Redux,我被迫開始寫一些遵循不可變原則的代碼。剛開始的時候確實有點不適應,不過后來我就意識到了這種方式的好處:它使得處理單向數據流更加容易。
不可變原則禁止修改對象。幸運的是,解構可以幫助你在遵循不可變原則的同時完成這些操作。
將解構與展開運算符(rest operator)結合使用來移除數組的第一個元素:
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" }
上述方法將解構與對象展開運算符結合起來使用,創建了一個新的對象small,這個新對象包含big對象除了foo屬性之外的所有屬性。
4. 解構可迭代的值
在前面幾部分內容中,都是解構的數組。實際上解構運算是可以用于所有的可迭代對象的。
許多原生的基礎類型和對象都是可迭代的,例如數組,類數組,字符串,set集合和map集合。
例如,你可以把字符串解構成單個字符:
const str = "cheese"; const [firstChar = ""] = str; firstChar; //=> 'c'
當然解構不僅僅限于原生可迭代的那幾種類型。解構可以被用于所有實現了迭代接口(iterable protocol)的對象。
如下所示,movies包含一個movie對象列表。我們想要解構movies對象的時候,可以獲取到電影的title這個字符串。實現這個操作首先需要自定義一個迭代器:
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
方法實現了一個迭代器。這個迭代器可以迭代所有電影的title屬性。
我們在movies對象上遵循了迭代接口實現,從而實現了通過解構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="Unknow" } = obj; return `Hello, ${name}!`; } greet({ name: "Batman" }, "name"); //=> Hello, Batman! greet( {}, "name" ); //=> Hello, Unknow!
greet()被調用時需要傳遞兩個參數,一個是對象,一個是屬性名稱。
在greet()函數內部,解構表達式const { [nameProp]: name="Unknow" } = obj;
使用中括號[nameProp]讀取動態屬性的名稱。name變量接收動態屬性的值。
更好的做法就是你可以指定一個默認的值Unknow以防屬性不存在的情況。
6. 總結
解構可以幫助你更方便快捷的訪問對象屬性和數組元素。
除了基本用法之外,數組解構還可以方便的交換變量,訪問數組元素,做一些遵循不可變原則的操作。
JavaScript提供了更多的可能性,因為你可以通過擴展迭代器實現自定義的解構邏輯。
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。