日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
為什么我喜歡JavaScript可選鏈

 很多 JavaScript 的特性極大地改變了你的編碼方式。從 ES2015 及更高版本開始,對我的代碼影響較大的功能是解構(gòu)、箭頭函數(shù)、類和模塊系統(tǒng)。

截至2019年8月,一項(xiàng)新提案可選鏈(optional chaining)進(jìn)入了第3階段,將是一個(gè)很好的改進(jìn)??蛇x的鏈接更改了從深層對象結(jié)構(gòu)訪問屬性的方式。

讓我們看看可選鏈?zhǔn)侨绾瓮ㄟ^在深度訪問可能缺少的屬性時(shí)刪除樣板條件和變量來簡化代碼的。

1. 問題

由于 JavaScript 的動(dòng)態(tài)特性,一個(gè)對象可以具有非常不同的對象嵌套結(jié)構(gòu)。

通常,你可以在以下情況下處理此類對象:

  • 獲取遠(yuǎn)程JSON數(shù)據(jù)
  • 使用配置對象
  • 具有可選屬性

盡管這為對象提供了支持不同數(shù)據(jù)的靈活性,但是在訪問此類對象的屬性時(shí),隨之而來的是增加了復(fù)雜性。

bigObject 在運(yùn)行時(shí)可以有不同的屬性集:

 
 
 
  1. // One version of bigObject 
  2. const bigObject = { 
  3.   // ... 
  4.   prop1: { 
  5.     //... 
  6.     prop2: { 
  7.       // ... 
  8.       value: 'Some value' 
  9.     } 
  10.   } 
  11. }; 
  12.  
  13. // Other version of bigObject 
  14. const bigObject = { 
  15.   // ... 
  16.   prop1: { 
  17.     // Nothing here    
  18.   } 
  19. }; 

因此你必須手動(dòng)檢查屬性是否存在:

 
 
 
  1. // Later 
  2. if (bigObject &&  
  3.     bigObject.prop1 != null &&  
  4.     bigObject.prop1.prop2 != null) { 
  5.   let result = bigObject.prop1.prop2.value; 

最好不要這樣寫,因?yàn)榘颂嗟臉影宕a。。

讓我們看看可選鏈?zhǔn)侨绾谓鉀Q此問題,從而減少樣板條件的。

2. 輕松深入訪問屬性

讓我們設(shè)計(jì)一個(gè)保存電影信息的對象。該對象包含 title 必填屬性,以及可選的 director 和 actor。

movieSmall 對象僅包含 title,而 movieFull 則包含完整的屬性集:

 
 
 
  1. const movieSmall = { 
  2.   title: 'Heat' 
  3. }; 
  4.  
  5. const movieFull = { 
  6.   title: 'Blade Runner', 
  7.   director: { name: 'Ridley Scott' }, 
  8.   actors: [{ name: 'Harrison Ford' }, { name: 'Rutger Hauer' }] 
  9. }; 

讓我們寫一個(gè)獲取導(dǎo)演姓名的函數(shù)。請注意 director 屬性可能會(huì)丟失:

 
 
 
  1. function getDirector(movie) { 
  2.   if (movie.director != null) { 
  3.     return movie.director.name; 
  4.   } 
  5.  
  6. getDirector(movieSmall); // => undefined 
  7. getDirector(movieFull);  // => 'Ridley Scott' 

if (movie.director) {...} 條件用于驗(yàn)證是否定義了 director 屬性。如果沒有這種預(yù)防措施,則在訪問movieSmall 對象的導(dǎo)演的時(shí),JavaScript 會(huì)引發(fā)錯(cuò)誤 TypeError: Cannot read property 'name' of undefined。

這是用了可選鏈功能并刪除 movie.director 存在驗(yàn)證的正確位置。新版本的 getDirector() 看起來要短得多:

 
 
 
  1. function getDirector(movie) { 
  2.   return movie.director?.name; 
  3.  
  4. getDirector(movieSmall); // => undefined 
  5. getDirector(movieFull);  // => 'Ridley Scott' 

在 movie.director?.name 表達(dá)式中,你可以找到 ?.:可選鏈運(yùn)算符。

對于 movieSmall,缺少屬性 director。結(jié)果 movie.director?.name 的計(jì)算結(jié)果為 undefined。可選鏈運(yùn)算符可防止引發(fā) TypeError: Cannot read property 'name' of undefined 錯(cuò)誤。

相反 movieFull 的屬性 director是可用的。 movie.director?.name 默認(rèn)被評估為 'Ridley Scott'。

簡而言之,代碼片段:

 
 
 
  1. let name = movie.director?.name; 

等效于:

 
 
 
  1. let name; 
  2. if (movie.director != null) { 
  3.   name = movie.director.name; 

?. 通過減少兩行代碼簡化了 getDirector() 函數(shù)。這就是為什么我喜歡可選鏈的原因。

2.1 數(shù)組項(xiàng)

可選鏈能還可以做更多的事。你可以在同一表達(dá)式中自由使用多個(gè)可選鏈運(yùn)算符。甚至可以用它安全地訪問數(shù)組項(xiàng)!

下一個(gè)任務(wù)編寫一個(gè)返回電影主角姓名的函數(shù)。

在電影對象內(nèi)部,actor 數(shù)組可以為空甚至丟失,所以你必須添加其他條件:

 
 
 
  1. function getLeadingActor(movie) { 
  2.   if (movie.actors && movie.actors.length > 0) { 
  3.     return movie.actors[0].name; 
  4.   } 
  5.  
  6. getLeadingActor(movieSmall); // => undefined 
  7. getLeadingActor(movieFull);  // => 'Harrison Ford' 

如果需要 if (movie.actors && movies.actors.length > 0) {...} ,則必須確保 movie 包含 actors 屬性,并且該屬性中至少有一個(gè) actor。

使用可選鏈,這個(gè)任務(wù)就很容易解決:

 
 
 
  1. function getLeadingActor(movie) { 
  2.   return movie.actors?.[0]?.name; 
  3.  
  4. getLeadingActor(movieSmall); // => undefined 
  5. getLeadingActor(movieFull);  // => 'Harrison Ford' 

actors?. 確保 actors 屬性存在。 [0]?. 確保列表中存在第一個(gè)參與者。這真是個(gè)好東西!

3. 默認(rèn)為Nullish合并

一項(xiàng)名為nullish 合并運(yùn)算符的新提案會(huì)處理 undefined 或 null ,將其默認(rèn)設(shè)置為特定值。

如果 variable 是 undefined 或 null,則表達(dá)式 variable ?? defaultValue 的結(jié)果為 defaultValue。否則,表達(dá)式的計(jì)算結(jié)果為 variable 值。

 
 
 
  1. const noValue = undefined; 
  2. const value = 'Hello'; 
  3.  
  4. noValue ?? 'Nothing'; // => 'Nothing' 
  5. value   ?? 'Nothing'; // => 'Hello' 

當(dāng)鏈評估為 undefined 時(shí),通過將默認(rèn)值設(shè)置為零,Nullish 合并可以改善可選鏈。

例如,讓我們更改 getLeading() 函數(shù),以在電影對象中沒有演員時(shí)返回 "Unknown actor" :

 
 
 
  1. function getLeadingActor(movie) { 
  2.   return movie.actors?.[0]?.name ?? 'Unknown actor'; 
  3.  
  4. getLeadingActor(movieSmall); // => 'Unknown actor' 
  5. getLeadingActor(movieFull);  // => 'Harrison Ford' 

4. 可選鏈的3種形式

你可以通過以下 3 種形式使用可選鏈。

第一種形式的 object.property 用于訪問靜態(tài)屬性:

 
 
 
  1. const object = null; 
  2. object?.property; // => undefined 

第二種形式 object?.[expression] 用于訪問動(dòng)態(tài)屬性或數(shù)組項(xiàng):

 
 
 
  1. const object = null; 
  2. const name = 'property'; 
  3. object?.[name]; // => undefined 
 
 
 
  1. const array = null; 
  2. array?.[0]; // => undefined 

最后,第三種形式 object?.([arg1, [arg2, ...]]) 執(zhí)行一個(gè)對象方法:

 
 
 
  1. const object = null; 
  2. object?.method('Some value'); // => undefined 

如果需要,可以將這些形式組合起來以創(chuàng)建長的可選鏈:

 
 
 
  1. const value = object.maybeUndefinedProp?.maybeNull()?.[propName]; 

5.短路:在null/undefined 處停止

可選鏈運(yùn)算符的有趣之處在于,一旦在其左側(cè) leftHandSide?.rightHandSide 上遇到空值,就會(huì)停止對右側(cè)訪問器的評估。這稱為短路。

看一個(gè)例子:

 
 
 
  1. const nothing = null; 
  2. let index = 0; 
  3.  
  4. nothing?.[index++]; // => undefined 
  5. index;              // => 0 

nothing 保留一個(gè)空值,因此可選鏈立即求值為 undefined,并跳過右側(cè)訪問器的求值。因?yàn)?index 的值沒有增加。

6. 何時(shí)使用可選鏈

要抵制使用可選鏈運(yùn)算符訪問任何類型屬性的沖動(dòng):這會(huì)導(dǎo)致錯(cuò)誤的用法。下一節(jié)將說明何時(shí)正確使用它。

6.1 可能無效的訪問屬性

必須僅在可能為空的屬性附近使用 ?.: maybeNullish?.prop。在其他情況下,請使用老式的屬性訪問器:.property 或 [propExpression]。

調(diào)用電影對象。查看表達(dá)式 movie.director?.name,因?yàn)?director 可以是 undefined,所以在 director 屬性附近使用可選鏈運(yùn)算符是正確的。

相反,使用 ?. 訪問電影標(biāo)題 movie?.title 沒有任何意義。電影對象不會(huì)是空的。

 
 
 
  1. // Good 
  2. function logMovie(movie) { 
  3.   console.log(movie.director?.name); 
  4.   console.log(movie.title); 
  5.  
  6. // Bad 
  7. function logMovie(movie) { 
  8.   // director needs optional chaining 
  9.   console.log(movie.director.name); 
  10.  
  11.   // movie doesn't need optional chaining 
  12.   console.log(movie?.title); 

6.2 通常有更好的選擇

以下函數(shù) hasPadding() 接受具有可選 padding 屬性的樣式對象。 padding 具有可選的屬性 left,top,right,bottom。

嘗試用可選鏈運(yùn)算符:

 
 
 
  1. function hasPadding({ padding }) { 
  2.   const top = padding?.top ?? 0; 
  3.   const right = padding?.right ?? 0; 
  4.   const bottom = padding?.bottom ?? 0; 
  5.   const left = padding?.left ?? 0; 
  6.   return left + top + right + bottom !== 0; 
  7.  
  8. hasPadding({ color: 'black' });        // => false 
  9. hasPadding({ padding: { left: 0 } });  // => false 
  10. hasPadding({ padding: { right: 10 }}); // => true 

雖然函數(shù)可以正確地確定元素是否具有填充,但是為每個(gè)屬性使用可選鏈?zhǔn)呛翢o必要的。

更好的方法是使用對象散布運(yùn)算符將填充對象默認(rèn)為零值:

 
 
 
  1. function hasPadding({ padding }) { 
  2.   const p = { 
  3.     top: 0, 
  4.     right: 0, 
  5.     bottom: 0, 
  6.     left: 0, 
  7.     ...padding 
  8.   }; 
  9.   return p.top + p.left + p.right + p.bottom !== 0; 
  10.  
  11. hasPadding({ color: 'black' });        // => false 
  12. hasPadding({ padding: { left: 0 } });  // => false 
  13. hasPadding({ padding: { right: 10 }}); // => true 

我認(rèn)為這一版本的 hasPadding() 可讀性更好。

7. 我為什么喜歡它?

我喜歡可選鏈運(yùn)算符,因?yàn)樗试S輕松地從嵌套對象中訪問屬性。它可以防止編寫針對訪問者鏈中每個(gè)屬性訪問器上的空值進(jìn)行驗(yàn)證的樣板代碼。

當(dāng)可選鏈與空值合并運(yùn)算符結(jié)合使用時(shí),可以得到更好的結(jié)果,從而更輕松地處理默認(rèn)值。


新聞標(biāo)題:為什么我喜歡JavaScript可選鏈
標(biāo)題網(wǎng)址:http://m.5511xx.com/article/codigdi.html