溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript可選鏈是什么

發(fā)布時間:2021-11-06 11:04:14 來源:億速云 閱讀:116 作者:iii 欄目:web開發(fā)

本篇內(nèi)容主要講解“JavaScript可選鏈是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JavaScript可選鏈是什么”吧!

1. 問題

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

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

  • 獲取遠程JSON數(shù)據(jù)

  • 使用配置對象

  • 具有可選屬性

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

bigObject 在運行時可以有不同的屬性集:

// One version of bigObject const bigObject = {   // ...   prop1: {     //...     prop2: {       // ...       value: 'Some value'     }   } };  // Other version of bigObject const bigObject = {   // ...   prop1: {     // Nothing here      } };

因此你必須手動檢查屬性是否存在:

// Later if (bigObject &&      bigObject.prop1 != null &&      bigObject.prop1.prop2 != null) {   let result = bigObject.prop1.prop2.value; }

最好不要這樣寫,因為包含了太多的樣板代碼。。

讓我們看看可選鏈是如何解決此問題,從而減少樣板條件的。

2. 輕松深入訪問屬性

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

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

const movieSmall = {   title: 'Heat' };  const movieFull = {   title: 'Blade Runner',   director: { name: 'Ridley Scott' },   actors: [{ name: 'Harrison Ford' }, { name: 'Rutger Hauer' }] };

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

function getDirector(movie) {   if (movie.director != null) {     return movie.director.name;   } }  getDirector(movieSmall); // => undefined getDirector(movieFull);  // => 'Ridley Scott'

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

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

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

在 movie.director?.name 表達式中,你可以找到 ?.:可選鏈運算符。

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

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

簡而言之,代碼片段:

let name = movie.director?.name;

等效于:

let name; if (movie.director != null) {   name = movie.director.name; }

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

2.1 數(shù)組項

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

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

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

function getLeadingActor(movie) {   if (movie.actors && movie.actors.length > 0) {     return movie.actors[0].name;   } }  getLeadingActor(movieSmall); // => undefined getLeadingActor(movieFull);  // => 'Harrison Ford'

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

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

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

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

3. 默認為Nullish合并

一項名為nullish 合并運算符的新提案會處理 undefined 或 null ,將其默認設(shè)置為特定值。

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

const noValue = undefined; const value = 'Hello';  noValue ?? 'Nothing'; // => 'Nothing' value   ?? 'Nothing'; // => 'Hello'

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

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

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

4. 可選鏈的3種形式

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

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

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

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

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

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

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

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

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

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

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

看一個例子:

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

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

6. 何時使用可選鏈

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

6.1 可能無效的訪問屬性

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

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

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

// Good function logMovie(movie) {   console.log(movie.director?.name);   console.log(movie.title); }  // Bad function logMovie(movie) {   // director needs optional chaining   console.log(movie.director.name);    // movie doesn't need optional chaining   console.log(movie?.title); }

6.2 通常有更好的選擇

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

嘗試用可選鏈運算符:

function hasPadding({ padding }) {   const top = padding?.top ?? 0;   const right = padding?.right ?? 0;   const bottom = padding?.bottom ?? 0;   const left = padding?.left ?? 0;   return left + top + right + bottom !== 0; }  hasPadding({ color: 'black' });        // => false hasPadding({ padding: { left: 0 } });  // => false hasPadding({ padding: { right: 10 }}); // => true

雖然函數(shù)可以正確地確定元素是否具有填充,但是為每個屬性使用可選鏈是毫無必要的。

更好的方法是使用對象散布運算符將填充對象默認為零值:

function hasPadding({ padding }) {   const p = {     top: 0,     right: 0,     bottom: 0,     left: 0,     ...padding   };   return p.top + p.left + p.right + p.bottom !== 0; }  hasPadding({ color: 'black' });        // => false hasPadding({ padding: { left: 0 } });  // => false hasPadding({ padding: { right: 10 }}); // => true

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

7. 我為什么喜歡它?

我喜歡可選鏈運算符,因為它允許輕松地從嵌套對象中訪問屬性。它可以防止編寫針對訪問者鏈中每個屬性訪問器上的空值進行驗證的樣板代碼。

當可選鏈與空值合并運算符結(jié)合使用時,可以得到更好的結(jié)果,從而更輕松地處理默認值。

到此,相信大家對“JavaScript可選鏈是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI