日韩无码专区无码一级三级片|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的OptionalChaining

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

創(chuàng)新新互聯(lián),憑借十余年的成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)經(jīng)驗(yàn),本著真心·誠心服務(wù)的企業(yè)理念服務(wù)于成都中小企業(yè)設(shè)計(jì)網(wǎng)站有上1000+案例。做網(wǎng)站建設(shè),選創(chuàng)新互聯(lián)建站。

截至 2019 年 8 月,一項(xiàng)新提案 optional chaining 達(dá)到了第3階段,這將是一個(gè)很好的改進(jìn)。Optional Chaining 改變了從深層對(duì)象結(jié)構(gòu)訪問屬性的方式。

下面讓我們來看看 optional chaining 是如何通過在深度訪問可能缺少的屬性時(shí)刪除樣板條件和變量來簡化代碼的。

1. 問題

由于 JavaScript 的動(dòng)態(tài)特性,對(duì)象可以有區(qū)別很大的嵌套對(duì)象結(jié)構(gòu)。

通常,你在以下情況下處理此類對(duì)象:

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

雖然這為對(duì)象提供了支持不同結(jié)構(gòu)數(shù)據(jù)的靈活性,但是在訪問這些對(duì)象的屬性時(shí)會(huì)增加復(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. // Other version of bigObject  
  13. const bigObject = {  
  14.   // ...  
  15.   prop1: {  
  16.     // Nothing here     
  17.   }  
  18. }; 

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

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

這會(huì)產(chǎn)生很多樣板代碼。如果不需要寫這些代碼那就太好了。

讓我們看看 optional chaining 如何解決這個(gè)問題,并減少樣板條件。

2. 輕松的深入訪問屬性

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

movieSmall 對(duì)象只包含 title,而 movieFull 包含完整的屬性集: 

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

讓我們寫一個(gè)獲取導(dǎo)演名字的函數(shù)。請(qǐng)記住,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 屬性是否已定義。如果沒有這個(gè)預(yù)防措施,在訪問movieSmall 對(duì)象 director 的時(shí)候,JavaScript 會(huì)拋出錯(cuò)誤 TypeError: Cannot read property 'name' of undefined。

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

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

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

在 movieSmall 的情況下,如果屬性 director 丟失了。那么 movie.director?.name 的計(jì)算結(jié)果為 undefined。 optional chaining 運(yùn)算符可防止拋出 TypeError:Cannot read property 'name' of undefined。

相反,在 movieFull 的情況下,屬性 director 可用。 movie.director?.name 的值為 'Ridley Scott'.。

簡單來說,代碼片段: 

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

相當(dāng)于: 

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

?. 通過減少 2 行代碼簡化了 getDirector() 函數(shù)。這就是我喜歡 optional chaining 的原因。

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

但是 optional chaining 功能可以做更多的事情。你可以在同一表達(dá)式中使用多個(gè)optional chaining 運(yùn)算符。甚至可以使用它來安全地訪問數(shù)組項(xiàng)目!

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

在 movie 對(duì)象中,actors 數(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。

通過使用 optional chaining,此任務(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è) actor 存在于列表中。很好!

3. nullish 合并

名為 nullish coalescing operator 的新提案建議用 ?? 處理 undefined或null,將它們默認(rèn)為特定的值。

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

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

當(dāng)評(píng)估為 undefined 時(shí),Nullish 合并可以通過默認(rèn)值來改進(jìn) optional chaining。

例如,當(dāng) movie 對(duì)象中沒有 actor時(shí),讓我們改變 getLeading() 函數(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. optional chaining 的 3 種形式

可以用以下 3 種形式使用 optional chaining 。

第一種形式 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  
  4. const array = null;  
  5. array?.[0]; // => undefined 

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

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

如果需要,可以通過組合這些表單來創(chuàng)建長的可選鏈: 

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

5. 短路:停止于 null/undefined

有關(guān) optional chaining 運(yùn)算符的有趣之處在于,只要在其左側(cè) leftHandSide?.rightHandSide 中遇到無效值,右側(cè)訪問器的評(píng)估就會(huì)停止。這稱為短路。

我們來看一個(gè)例子: 

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

nothing 保持一個(gè) nullish 值,因此 optional chaining 評(píng)估為 undefined ,并跳過右側(cè)訪問器的評(píng)估。因?yàn)?index 編號(hào)不會(huì)增加。

6. 何時(shí)使用 optional chaining

一定要克制使用 optional chaining 操作符訪問任何類型屬性的沖動(dòng):這將會(huì)導(dǎo)致誤導(dǎo)使用。下一節(jié)將介紹何時(shí)正確使用它。

6.1 訪問可能無效的屬性

?. 必須只在可能無效的屬性附近使用:maybeNullish?.prop。在其他情況下,使用舊的屬性訪問器:.property 或 [propExpression]。

回想一下 movie 對(duì)象。查看表達(dá)式 movie.director?.name,因 為director 可以是 undefined,在director屬性附近使用 optional chaining 運(yùn)算符是正確的。

相反,使用 ?. 來訪問電影標(biāo)題是沒有意義的:movie?.title。movie 對(duì)象不會(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.   // movie doesn't need optional chaining  
  11.   console.log(movie?.title);  

6.2 通常有更好的選擇

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

下面嘗試使用 optional chaining 運(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ù)正確地確定元素是否具有填充,但是對(duì)于每個(gè)屬性都使用 optional chaining 是非常困難的。

更好的方法是使用對(duì)象擴(kuò)展運(yùn)算符將填充對(duì)象默認(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 

在我看來,這個(gè)版本的 hasPadding() 更容易閱讀。

7. 為什么我喜歡它?

我喜歡 optional chaining 運(yùn)算符,因?yàn)樗试S從嵌套對(duì)象輕松訪問屬性。它可以減少通過編寫樣板文件來驗(yàn)證來自訪問器鏈的每個(gè)屬性訪問器上無效值的工作。

當(dāng) optional chaining 與無效合并運(yùn)算符組合時(shí),你可以獲得更好的結(jié)果,能夠更輕松地處理默認(rèn)值。


網(wǎng)頁名稱:為什么我喜歡JavaScript的OptionalChaining
當(dāng)前路徑:http://m.5511xx.com/article/dpsdiio.html