国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

深入淺出講解ES6的解構(gòu)

2019-11-20 09:19:12
字體:
供稿:網(wǎng)友

什么是解構(gòu)?

解構(gòu)與構(gòu)造數(shù)據(jù)截然相反。 例如,它不是構(gòu)造一個(gè)新的對(duì)象或數(shù)組,而是逐個(gè)拆分現(xiàn)有的對(duì)象或數(shù)組,來提取你所需要的數(shù)據(jù)。

ES6使用了一種新模式來匹配你想要提取的數(shù)值, 解構(gòu)賦值就是采用了這種模式。 該模式會(huì)映射出你正在解構(gòu)的數(shù)據(jù)結(jié)構(gòu),只有那些與該模式相匹配的數(shù)據(jù),才會(huì)被提取出來。

被解構(gòu)的數(shù)據(jù)項(xiàng)位于賦值運(yùn)算符 = 的右側(cè),可以是任何數(shù)組和對(duì)象的組合,允許隨意嵌套。用于給這些數(shù)據(jù)賦值的變量個(gè)數(shù)不限。

數(shù)組解構(gòu)

數(shù)組解構(gòu) 使用一個(gè)數(shù)組作為一個(gè)數(shù)據(jù)項(xiàng),你可以根據(jù) 數(shù)組模式 (用于從數(shù)組中匹配你所需要的數(shù)值)從這個(gè)數(shù)組里面提取數(shù)值給一個(gè)或者多個(gè)變量賦值。

數(shù)組模式 是根據(jù)數(shù)值的位置來鑒別哪些值是你想要提取的。它必須能精確地映射數(shù)組的結(jié)構(gòu),來要讓數(shù)組模式中的每個(gè)變量都被賦上 被解構(gòu)數(shù)組中 位置與之相對(duì)應(yīng)的值。

舉幾個(gè)例子來幫助我們理解吧:

數(shù)組模式示例

把數(shù)組中所有的數(shù)值賦給一個(gè)個(gè)單獨(dú)的變量

   // 設(shè)置數(shù)組  const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff'];  // 把數(shù)組解構(gòu)賦值給變量。數(shù)組模式位于賦值運(yùn)算符 `=` 的左側(cè),被結(jié)構(gòu)的數(shù)組在  // 其右側(cè)。  const [ironMan, cap, blackWidow] = avengers;  // ironMan = 'Tony Stark'   // cap = 'Steve Rogers'  // blackWidow = 'Natasha Romanoff'  // 輸出 ironMan:  ironMan;

提取除第一個(gè)外的所有數(shù)值

 const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff'];  // 我們不用用到Tony  const [, cap, blackWidow] = avengers;  // ironMan = Error: undefined   // cap = 'Steve Rogers'  // blackWidow = 'Natasha Romanoff'  // 輸出 cap:  cap;

提取除第二個(gè)外的所有數(shù)值

 const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff'];  // cap 缺失  const [ironMan, , blackWidow] = avengers;  // ironMan = 'Tony Stark'   // cap = Error: undefined  // blackWidow = 'Natasha Romanoff'  // 輸出 blackWidow:  blackWidow;

提取除最后一個(gè)外的所有數(shù)值

 const avengers = ['Tony Stark', 'Steve Rogers', 'Natasha Romanoff'];  // ironMan vs cap  const [ironMan, cap] = avengers;  // ironMan = 'Tony Stark'   // cap = 'Steve Rogers'  // blackWidow = Error: undefined  // 輸出 blackWidow:  ironMan;

嵌套數(shù)組

這種匹配模式也支持嵌套數(shù)組,只要保證賦值運(yùn)算符 = 左側(cè)的數(shù)組模式與右側(cè)的數(shù)組結(jié)構(gòu)相匹配即可。再次說明一下,= 左邊的變量都會(huì)被賦上 = 右側(cè)數(shù)組中位置與之相對(duì)應(yīng)的值。 無論你怎么深層次地嵌套,仍可以對(duì)它們進(jìn)行解構(gòu)。

解構(gòu)嵌套的數(shù)組

 // Destructuring Nested Arrays  const avengers = [            'Natasha Romanoff',             ['Tony Stark', 'James Rhodes'],             ['Steve Rogers', 'Sam Wilson']          ];  // Avengers and their partners  const [blackWidow, [ironMan, warMachine], [cap, falcon]] = avengers;  // blackWidow = 'Natasha Romanoff'  // ironMan = 'Tony Stark'  // warMachine = 'James Rhodes'  // cap = 'Steve Rogers'  // falcon = 'Sam Wilson'  // Output warMachine:  warMachine;

從深層嵌套的數(shù)組中提取一個(gè)值

 // 從該數(shù)組中提取 Pepper Potts  const avengers = [            'Natasha Romanoff',             [['Tony Stark', 'Pepper Potts'], 'James Rhodes'],             ['Steve Rogers', 'Sam Wilson']          ];  // Destructure  const [ , // 跳過 'Natasha Romanoff'       [[ , // 跳過 'Tony Stark'       hera // Pepper Potts 賦值給變量 'hera'     ]]] = avengers;  // 請(qǐng)注意:你也可以這樣寫  // const [, [[, hera ]]] = avengers;  // 輸出 hera:  hera;  // hera = 'Pepper Potts'

運(yùn)用rest操作符捕獲所有剩余項(xiàng)

如果你想要獲取特定的數(shù)組項(xiàng),并且把剩余的項(xiàng)歸在一個(gè)數(shù)組,那么你可以這樣運(yùn)用 rest操作符 來解構(gòu):

 // 通過rest操作符解構(gòu)  const avengers = ['Natasha Romanoff', 'Tony Stark', 'Steve Rogers'];  const [blackWidow, ...theOthers] = avengers;  theOthers;  // blackWidow = 'Natasha Romanoff'  // theOthers = ['Tony Stark', 'Steve Rogers']  // 輸出 theOthers:  theOthers;

對(duì)象解構(gòu)

對(duì)象解構(gòu)就更神奇了,尤其是當(dāng)你需要從一個(gè)復(fù)雜的、深層嵌套的對(duì)象中取值時(shí),其作用更加明顯。重申一下,對(duì)象解構(gòu)與數(shù)組解構(gòu)用的是同樣的規(guī)則(即在賦值運(yùn)算符左側(cè)創(chuàng)建一個(gè) 對(duì)象模式, 使它的變量位置與 = 右側(cè)對(duì)象的值位置相匹配)。

在對(duì)象解構(gòu)中,你需要指明那些需要被提取值的屬性名稱,以及將要被賦值的變量名。跟數(shù)組解構(gòu)一樣,我們需要在賦值運(yùn)算符左邊先創(chuàng)建一個(gè)對(duì)象模式來映射被解構(gòu)的對(duì)象。

盡管在這種情況下,我們想要提取的是 對(duì)象屬性的值 (如:我們從 { prop: value } 中提取 value)。相應(yīng)地,我們的對(duì)象模式必須有一個(gè)變量,這個(gè)變量的位置要跟我們即將提取的屬性值所在的位置一致。

簡(jiǎn)單示例

提取一個(gè)簡(jiǎn)單的對(duì)象屬性值

我們可以這樣做,來將對(duì)象 { ironMan: 'Tony Stark' } 的屬性 ironMan 的值 'Tony Stark' 賦值給變量 a

 //解構(gòu)對(duì)象的屬性值,賦給單個(gè)變量 `a`: const { ironMan: a } = { ironMan: 'Tony Stark' }; // 輸出 a: a;  // a = 'Tony Stark '

提取多個(gè)屬性值

我們只要拓展相同的模式,就可以從一個(gè)對(duì)象中提取多個(gè)屬性值,如下:

 // Setup our object const avengers = {  ironMan: 'Tony Stark',   cap: 'Steve Rogers',   blackWidow: 'Natasha Romanoff' }; // Destructure object to individual variables const {   ironMan: a,   cap: b,   blackWidow: c  } = avengers; // a = 'Tony Stark ' // b = 'Steve Rogers' // c ='Natasha Romanoff' // Output a: a;

觀察一下這個(gè)解構(gòu)模式是怎么確切地匹配 被解構(gòu)對(duì)象 的。

嵌套的對(duì)象解構(gòu)

像解構(gòu)嵌套數(shù)組一樣,我們可以對(duì)嵌套對(duì)象進(jìn)行解構(gòu),不管它的層級(jí)多深。

 // Setup our object const avengers = {  blackWidow: 'Natasha Romanoff',  ironManCharacters: {   couple: {    ironMan: 'Tony Stark',     hera: 'Pepper Potts',    },    partner: {       warMachine: 'James Brodie'    }  },  capCharacters: {   cap: 'Steve Rogers',    partner: {    falcon: 'Sam Wilson'   }  } }; // Destructure object to individual variables const {   blackWidow: a,  ironManCharacters: {    couple: {    ironMan: b,    hera: c  },   partner: {    warMachine: d   }  },  capCharacters: {   cap: e,   partner: {    falcon: f   }  } } = avengers; // a = 'Natasha Romanoff' // b = 'Tony Stark ' // c = 'Pepper Potts' // d = 'James Brodie' // e = 'Steve Rogers' // f = 'Sam Wilson' // Output a: a;

給賦值的變量命名

當(dāng)然,把變量名設(shè)為諸如 a, b, c 之類,是很糟糕的,變量名稱應(yīng)該是有意義的。

冗長(zhǎng)式命名

 // Setup our object const avengers = {  ironMan: 'Tony Stark',   cap: 'Steve Rogers',   blackWidow: 'Natasha Romanoff' }; // Destructure object to individual variables with meaningful names const {   ironMan: ironMan,  cap: cap,   blackWidow: blackWidow } = avengers; // blackWidow = 'Natasha Romanoff' // ironMan = 'Tony Stark ' // cap = 'Steve Rogers' // Output blackWidow: blackWidow;

這種做法比上面用 a,b,c 命名好,但是仍然可以完善。 { ironMan: ironMan } 看起來有點(diǎn)丑而且不直觀。

語法上命名捷徑

如果你要把一個(gè)對(duì)象的屬性值賦給一個(gè)變量,該變量的名稱跟對(duì)象的屬性名稱一樣,那么在 = 左側(cè)的賦值模式里面,你只需要簡(jiǎn)單地寫屬性名即可,如下:

 // Setup our object const avenger = {  ironMan: 'Tony Stark' }; // Destructure object to individual variables with meaningful names const {   ironMan  // equivalent to 'ironMan: ironMan' } = avenger; // ironMan = 'Tony Stark ' // Output ironMan: ironMan;

由于 被解構(gòu)的對(duì)象屬性名稱 跟 被賦值的變量名稱 相同,我們只需要把名稱列出來一次即可。

語法簡(jiǎn)潔

我們稍微重新修整下前面的代碼,就可以使它們看起來更加簡(jiǎn)潔明了:

 // Setup our object const avengers = {  ironMan: 'Tony Stark',   cap: 'Steve Rogers',   blackWidow: 'Natasha Romanoff' }; // Destructure object to individual variables with meaningful names const { ironMan, cap, blackWidow } = avengers; // Output ironMan: ironMan;

從對(duì)象中提取一個(gè)深層嵌套的屬性

當(dāng)我們要提取一個(gè)深層嵌套的對(duì)象屬性時(shí),事情就更有趣了:

 // Setup our objectconst avengers = {  blackWidow: 'Natasha Romanoff',  ironManCharacters: {   couple: {     ironMan: 'Tony Stark',     hera: 'Pepper Potts',   },   partner: {     warMachine: 'James Brodie'   }  },  capCharacters: {   cap: 'Steve Rogers',   partner: {     falcon: 'Sam Wilson'   }  }};// Destructure a deeply nested objectconst { ironManCharacters: { couple } } = avengers;// couple = {//  ironMan: 'Tony Stark', //  hera: 'Pepper Potts',// }// Output couple:couple;

等等,你是怎么閱讀這段代碼的?couple 這個(gè)變量又是怎么被定義的呢?

通過這樣拆分,我們就可以看出賦值運(yùn)算符 = 左側(cè)是被解構(gòu)對(duì)象的一個(gè)映射:

 const avengers = {  ironManCharacters: {   couple: {     ironMan: 'Tony Stark',      hera: 'Pepper Potts',   }  }};const {   ironManCharacters: {    couple   }} = avengers;// Output couple:couple;

僅僅使用 const { couple } = avengers; 并沒有辦法提取出 couple 的值。只有把要提取的對(duì)象屬性的 位置和名稱映射出來,JS 編譯器才能得到相應(yīng)的信息,沿著對(duì)象的所有屬性往下查找,并準(zhǔn)確地提取我們想要的值。

這里也要注意到 couple 用了語法捷徑給變量命名,實(shí)際上是這樣的:

const {   ironManCharacters: {    couple: couple  }} = avengers;

couple 就是這樣被定義的,它的值就是對(duì)象 avengers 中屬性名為 couple 的值。

給對(duì)象的屬性解構(gòu)賦值

到目前為止,我們都是解構(gòu)對(duì)象的值來給單個(gè)的變量賦值,其實(shí)還可以給另一個(gè)對(duì)象的屬性賦值。

 const avengers = { blackWidow: 'Natasha Romanoff', ironManCharacters: {  couple: {   ironMan: 'Tony Stark',   hera: 'Pepper Potts'  } }};const ironManProperties = { family: {}};({ ironManCharacters: {  couple: ironManProperties.family }} = avengers);ironManProperties.family// ironManProperties.family = {//  ironMan: 'Tony Stark',//  hera: 'Pepper Potts'// }// Output ironManProperties.family:ironManProperties.family;

在這里我們把 ironManCharacters.couple 的值賦給了 ironManProperties.family 這個(gè)屬性,這里有兩點(diǎn)需要說明一下:

1.解構(gòu)賦值必須被包含在 圓括號(hào) 內(nèi)

當(dāng)我們?cè)趯?duì)一個(gè)已存在的變量(如上面例子中的 ironManProperties)進(jìn)行解構(gòu)時(shí),一定要這樣做,而不是去聲明一個(gè)新的變量。

2.模式仍然相匹配

{ ironManCharacters: { couple... } } 與對(duì)象 avengers 中的 ironManCharacters 相匹配。這樣就能如你所愿,從 avengers 對(duì)象中提取出 ironManCharacters.couple 的值了。但是現(xiàn)在,couple 后面放置了一個(gè)新的對(duì)象ironManProperties 和它的屬性 family,其實(shí)被賦值的就是這個(gè)對(duì)象的屬性ironManProperties.family了。

當(dāng)你嘗試把這種情況解釋清楚時(shí),是否還有所困惑呢?在jsfiddle里面嘗試上面的代碼,一切就明了了。

如果你不清楚自己為什么要這樣做,請(qǐng)參考下一篇文章的例子。這些例子會(huì)告訴你,為什么采用這種模式來解構(gòu)API調(diào)用的 JSON 對(duì)象,讓你領(lǐng)略解構(gòu)的神奇之處!

默認(rèn)值

解構(gòu)時(shí),你還可以給變量指定一個(gè)默認(rèn)值:

 // Setup our object const avengers = {  ironMan: 'Tony Stark',   cap: 'Steve Rogers',   blackWidow: 'Natasha Romanoff' }; // Destructure using defaults const { ironMan, cap, blackWidow, theHulk='Bruce Banner' } = avengers; // ironMan = 'Tony Stark'  // cap = 'Steve Rogers' // blackWidow = 'Natasha Romanoff' // theHulk = 'Bruce Banner' // Output blackWidow: blackWidow;

解構(gòu)時(shí)要避免出現(xiàn)這些問題

解構(gòu)賦值時(shí)沒有使用 const, let, var

在講到對(duì) 對(duì)象屬性 進(jìn)行解構(gòu)賦值時(shí)就已經(jīng)提及了這一點(diǎn),但這里還是有必要再重申一下,讓大家有個(gè)深刻的印象。

不能對(duì)已經(jīng)聲明的變量進(jìn)行解構(gòu)

也就是說,你只能在對(duì)變量解構(gòu)賦值的同時(shí)聲明變量。

 // Setup our object  const avengers = {   ironMan: 'Tony Stark',    cap: 'Steve Rogers',    blackWidow: 'Natasha Romanoff',   theHulk: 'Bruce Banner'  };  // Valid destructuring  const { ironMan } = avengers;  let { cap } = avengers;  var { blackWidow } = avengers;  // Invalid destructuring  let theHulk;  { theHulk } = avengers;  // Error  // Output theHulk:  theHulk;

為何不能對(duì)一個(gè)已經(jīng)聲明的變量進(jìn)行解構(gòu)呢?那是因?yàn)檫@時(shí)如果你使用了花括號(hào) { ,JavaScript會(huì)認(rèn)為你是在聲明一個(gè) block

解決的辦法就是把整個(gè)解構(gòu)賦值用一對(duì) 圓括號(hào) 括起來。

如何對(duì)一個(gè)已聲明的變量進(jìn)行解構(gòu)賦值

 // Setup our object  const avengers = {   ironMan: 'Tony Stark',    cap: 'Steve Rogers',    blackWidow: 'Natasha Romanoff',   theHulk: 'Bruce Banner'  };  // A valid Hulk  let theHulk;  ({ theHulk } = avengers);  // theHulk = 'Bruce Banner'  // Output theHulk:  theHulk;

現(xiàn)在我們不是以花括號(hào)開頭,所以JS不會(huì)認(rèn)為我們是在聲明一個(gè) block ,這樣就可以達(dá)到預(yù)期的解構(gòu)結(jié)果。

直接返回一個(gè)被解構(gòu)的值

在沒有先聲明一個(gè)接下來要被返回的變量時(shí),就直接返回一個(gè)被解構(gòu)的值,這樣是無法達(dá)到預(yù)期效果的。例如,下面的代碼中,返回的將是整個(gè) ironMan對(duì)象,而不是預(yù)期要的值 Tony Stark

 // Note: this doesn't work! function getTonyStark(avengers){  return { ironMan: { realName } } = avengers;  // return the avengers object, not the realName value } const avengers = {  ironMan: {   realName: 'Tony Stark'  } }; const tonyStark = getTonyStark(avengers); // tonyStark = { //  ironMan: { //   realName: 'Tony Stark' //  } // }; // Output tonyStark: tonyStark;

要從一個(gè)被解構(gòu)的對(duì)象中提取值,必須先把它賦值給一個(gè)變量,然后再把這個(gè)變量返回,如下代碼所示:

 // Note: this DOES work! function getTonyStark(avengers){  const { ironMan: { realName } } = avengers;  return realName; } const avengers = {  ironMan: {   realName: 'Tony Stark'  } }; const tonyStark = getTonyStark(avengers); // tonyStark = 'Tony Stark' // Output tonyStark: tonyStark;

這種把賦值和返回分成兩行代碼的做法實(shí)在惹人厭煩,代碼丑陋,也顯得沒必要。但很不幸,JavaScript就是這樣工作的----你必須先把解構(gòu)的值賦給一個(gè)變量,然后再把它返回,兩步必須分開做。

但是,沒有說我們只是說分開做,并沒有說一定要擺成兩行代碼,所以像下面這樣寫成一行,也是能達(dá)到預(yù)期效果的:

 function getTonyStark(avengers){  return ({ ironMan: { realName } } = avengers) && realName; } const avengers = {  ironMan: {   realName: 'Tony Stark'  } }; const tonyStark = getTonyStark(avengers); // tonyStark = 'Tony Stark' // Output tonyStark: tonyStark;

由于JavaScript的 _short-circuit_ 邏輯操作符 (&& and ||) 會(huì)基于第一個(gè)操作數(shù)的值來返回第二個(gè)操作數(shù)的值,所以這種寫法能夠達(dá)到預(yù)期效果。這里,第一個(gè)操作數(shù)是解構(gòu)賦值表達(dá)式,把值賦給 realName。而 realName 也就是第二個(gè)操作數(shù),所以它的值最終被返回。

這樣做不是最佳的,但是能實(shí)現(xiàn)。在追求代碼簡(jiǎn)短的同時(shí),一定要注意代碼的可讀性。

總結(jié)
本文深入講解了 解構(gòu)賦值 的主要原則。解構(gòu)不僅能減少你的代碼量,還能從根本上改變你的編碼方式。用的越多,你就會(huì)發(fā)現(xiàn)越多塑造數(shù)據(jù)和函數(shù)的方式,這些實(shí)現(xiàn)方式在過去幾乎是不可能的。希望本文對(duì)大家學(xué)習(xí)ES6有所幫助。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 久治县| 玛曲县| 永丰县| 巴楚县| 扎鲁特旗| 陆良县| 定边县| 敖汉旗| 化州市| 德钦县| 夏河县| 揭东县| 上栗县| 苍南县| 碌曲县| 孟津县| 新和县| 庆元县| 西乡县| 浙江省| 蒲城县| 交城县| 丹阳市| 虞城县| 扬州市| 河津市| 崇仁县| 文登市| 上饶县| 化隆| 陵水| 甘肃省| 黄梅县| 泰兴市| 平阴县| 泽州县| 社旗县| 南岸区| 辉南县| 常熟市| 乌拉特中旗|