關(guān)于JS解構(gòu)的5種有趣用法
前言
原文標(biāo)題:5 Interesting Uses of JavaScript Destructuring
原文鏈接:dmitripavlutin.com/5-interesti…
定期回顧我寫的JS代碼,我發(fā)現(xiàn)解構(gòu)運(yùn)算無處不在。
獲取對(duì)象的屬性和訪問數(shù)組內(nèi)容是都是很常用的操作。而解構(gòu)運(yùn)算使得這些操作變得非常簡(jiǎn)單明了。
在這篇文章中,我將會(huì)講解JS解構(gòu)不同于常見用法的五種使用技巧。
1. 交換變量
常見的交互兩個(gè)變量值的方法都需要借助一個(gè)額外的變量,看一個(gè)簡(jiǎn)單的例子:
let a = 1; let b = 2; let temp; temp = a; a = b; b = temp; a; // => 2 b; // => 1
temp是一個(gè)臨時(shí)變量,在例子中存儲(chǔ)了變量a的值,b的值賦給了a,最后把temp的值賦給了b。
解構(gòu)運(yùn)算使得交換變量的值變得非常簡(jiǎn)單,不需要借助第三個(gè)臨時(shí)變量:
let a = 1; let b = 2; [a, b] = [b, a]; a; // => 2 b; // => 1
[a, b] = [b, a]是一個(gè)解構(gòu)運(yùn)算。在等號(hào)的右側(cè),創(chuàng)建了一個(gè)數(shù)組[b, a],對(duì)應(yīng)的值為[2, 1]。數(shù)組的第一個(gè)值2被解構(gòu)賦值給了a,第二項(xiàng)1被解構(gòu)賦值給了b。
即使這種方式仍然創(chuàng)建了一個(gè)臨時(shí)數(shù)組,但是解構(gòu)賦值對(duì)于交換變量的值仍然是非常高效簡(jiǎn)單的方式。
這種方式并沒有什么限制。你還可以同時(shí)交互更多的變量值,比如:
let zero = 2; let one = 1; let two = 0; [zero, one, two] = [two, one, zero]; zero; //=> 0 one; //=> 1 two; //=> 2
你可以交換任意數(shù)量的變量值,只是兩個(gè)變量值的交換的情況更加常見。
2. 訪問數(shù)組
有一個(gè)數(shù)組,這個(gè)數(shù)組有可能是空的。有一種需求是訪問任意位置數(shù)組元素,如果這個(gè)位置為空,則返回一個(gè)默認(rèn)值。
通常情況下有的人可能會(huì)使用數(shù)組的length屬性做判斷:
const colors = []; let firstColor = "white"; if (colors.length > 0) { firstColor = colors[0]; } firstColor; //=> "white"
幸運(yùn)的是,數(shù)組解構(gòu)可以更快捷高效的實(shí)現(xiàn)相同的效果:
const colors = []; const [firstColor = "white"] = colors; firstColor; //=> "white"
const [firstColor = "white"] = colors;
將colors數(shù)組的第一個(gè)元素賦值給了變量firstColor。如果這個(gè)數(shù)組的下標(biāo)為0的位置上沒有任何元素(注:為undefined時(shí)即認(rèn)為為空),white將作為默認(rèn)值賦值給firstColor。
數(shù)組解構(gòu)是非常靈活的,如果你只想訪問數(shù)組的第二個(gè)元素,方法如下所示:
const colors = []; const [, secondColor = "black"] = colors; secondColor; //=> "black"
在解構(gòu)表達(dá)式的左邊寫一個(gè)逗號(hào):意味著數(shù)組的第一個(gè)元素被忽略掉。colors數(shù)組下標(biāo)為1的元素被解構(gòu)賦值給了變量secondColor。
3. 不可變操作
從我開始使用React,到后來的Redux,我被迫開始寫一些遵循不可變?cè)瓌t的代碼。剛開始的時(shí)候確實(shí)有點(diǎn)不適應(yīng),不過后來我就意識(shí)到了這種方式的好處:它使得處理單向數(shù)據(jù)流更加容易。
不可變?cè)瓌t禁止修改對(duì)象。幸運(yùn)的是,解構(gòu)可以幫助你在遵循不可變?cè)瓌t的同時(shí)完成這些操作。
將解構(gòu)與展開運(yùn)算符(rest operator)結(jié)合使用來移除數(shù)組的第一個(gè)元素:
const numbers = [1,2,3]; const [, ...fooNumbers] = numbers; fooNumbers; //=> [2, 3] numbers; //=> [1,2,3]
這個(gè)解構(gòu)操作[, ...fooNumbers] = numbers
創(chuàng)建了一個(gè)新的數(shù)組fooNumbers,這個(gè)數(shù)組包含numbers除了第一個(gè)元素外的其余元素。
numbers數(shù)組并沒有被改變,這種方式遵循了不可變?cè)瓌t。
除此之外,你也可以在遵循不可變?cè)瓌t的同時(shí)使用同樣的方法來刪除一個(gè)對(duì)象的屬性。如下所示,刪除big對(duì)象的foo屬性:
const big = { foo: "value foo", bar: "value bar", } const { foo, ...small } = big; small; //=> { bar: "value bar" } big; //=>{ foo: "value foo", bar: "value bar" }
上述方法將解構(gòu)與對(duì)象展開運(yùn)算符結(jié)合起來使用,創(chuàng)建了一個(gè)新的對(duì)象small,這個(gè)新對(duì)象包含big對(duì)象除了foo屬性之外的所有屬性。
4. 解構(gòu)可迭代的值
在前面幾部分內(nèi)容中,都是解構(gòu)的數(shù)組。實(shí)際上解構(gòu)運(yùn)算是可以用于所有的可迭代對(duì)象的。
許多原生的基礎(chǔ)類型和對(duì)象都是可迭代的,例如數(shù)組,類數(shù)組,字符串,set集合和map集合。
例如,你可以把字符串解構(gòu)成單個(gè)字符:
const str = "cheese"; const [firstChar = ""] = str; firstChar; //=> 'c'
當(dāng)然解構(gòu)不僅僅限于原生可迭代的那幾種類型。解構(gòu)可以被用于所有實(shí)現(xiàn)了迭代接口(iterable protocol)的對(duì)象。
如下所示,movies包含一個(gè)movie對(duì)象列表。我們想要解構(gòu)movies對(duì)象的時(shí)候,可以獲取到電影的title這個(gè)字符串。實(shí)現(xiàn)這個(gè)操作首先需要自定義一個(gè)迭代器:
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對(duì)象通過定義Symbol.iterator
方法實(shí)現(xiàn)了一個(gè)迭代器。這個(gè)迭代器可以迭代所有電影的title屬性。
我們?cè)趍ovies對(duì)象上遵循了迭代接口實(shí)現(xiàn),從而實(shí)現(xiàn)了通過解構(gòu)movies來獲取到標(biāo)題,比如我們獲取第一個(gè)電影的標(biāo)題:const [firstMovieTitle] = movies;
。
解構(gòu)用法的上限就是沒有上限。
5. 解構(gòu)動(dòng)態(tài)屬性
在我的經(jīng)驗(yàn)中,解構(gòu)一個(gè)對(duì)象的屬性要遠(yuǎn)比解構(gòu)一個(gè)數(shù)組的情況更多。
解構(gòu)對(duì)象看起來非常的簡(jiǎn)單:
const movie = { title: "Heat" }; const { title } = movie; title; //=> Heat
const { title } = movie;
創(chuàng)建了一個(gè)變量title,然后把movie.title的值賦值給了這個(gè)變量。
當(dāng)我第一次了解到對(duì)象解構(gòu)的時(shí)候,有一點(diǎn)令我驚訝的是你并不需要預(yù)先知道屬性的靜態(tài)名稱。你可以通過動(dòng)態(tài)屬性名來解構(gòu)一個(gè)對(duì)象。
為了了解動(dòng)態(tài)解構(gòu)的工作原理,我們來寫一個(gè)打招呼的函數(shù)作為例子:
function greet( obj, nameProp ) { const { [nameProp]: name="Unknow" } = obj; return `Hello, ${name}!`; } greet({ name: "Batman" }, "name"); //=> Hello, Batman! greet( {}, "name" ); //=> Hello, Unknow!
greet()被調(diào)用時(shí)需要傳遞兩個(gè)參數(shù),一個(gè)是對(duì)象,一個(gè)是屬性名稱。
在greet()函數(shù)內(nèi)部,解構(gòu)表達(dá)式const { [nameProp]: name="Unknow" } = obj;
使用中括號(hào)[nameProp]讀取動(dòng)態(tài)屬性的名稱。name變量接收動(dòng)態(tài)屬性的值。
更好的做法就是你可以指定一個(gè)默認(rèn)的值Unknow以防屬性不存在的情況。
6. 總結(jié)
解構(gòu)可以幫助你更方便快捷的訪問對(duì)象屬性和數(shù)組元素。
除了基本用法之外,數(shù)組解構(gòu)還可以方便的交換變量,訪問數(shù)組元素,做一些遵循不可變?cè)瓌t的操作。
JavaScript提供了更多的可能性,因?yàn)槟憧梢酝ㄟ^擴(kuò)展迭代器實(shí)現(xiàn)自定義的解構(gòu)邏輯。
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
JavaScript Rxjs mergeMap 的使用場(chǎng)合
這篇文章主要介紹了JavaScript Rxjs mergeMap 的使用場(chǎng)合,mergeMap 接收一個(gè)函數(shù)作為輸入?yún)?shù),這個(gè)函數(shù)的輸入?yún)?shù)就是通過 pipe 鏈接 mergeMap 的 Observable 里包含的元素2022-07-07JavaScript實(shí)現(xiàn)10秒后再次獲取驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)10秒后再次獲取驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12javascript offsetX與layerX區(qū)別
FF沒有offsetX屬性,有個(gè)layerX屬性,只要將事件源的位置設(shè)置成相對(duì)定位(position:relative)或絕對(duì)定位(position:absolute),兩者結(jié)果就相等,表示事件源相對(duì)于父元素的X坐標(biāo)。2010-03-03Javascript 5種方法實(shí)現(xiàn)過濾刪除前后所有空格
這篇文章主要介紹Javascript 5種過濾刪除前后所有空格的方法,比較實(shí)用,需要的朋友可以參考下。2016-06-06JavaScript實(shí)現(xiàn)的選擇排序算法實(shí)例分析
這篇文章主要介紹了JavaScript實(shí)現(xiàn)的選擇排序算法,結(jié)合實(shí)例形式分析了選擇排序的原理、實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-04-04javascript數(shù)字?jǐn)?shù)組去重復(fù)項(xiàng)的實(shí)現(xiàn)代碼
console.log 不支持ie,下面的代碼需要在火狐中測(cè)試,不然會(huì)有問題。2010-12-12