JS?可選鏈的三種形勢(shì)及好處詳解
引言
JS的一些特性極大地改變了咱們的編碼方式。從ES6年開(kāi)始,對(duì)咱們代碼影響最大的特性的解 、箭頭函數(shù)、類和模塊系統(tǒng)。
到2019年8月,一個(gè)新的可選鏈提案已經(jīng)進(jìn)入第三階段,這是一個(gè)很好的改進(jìn)??蛇x鏈接改變了從深層對(duì)象結(jié)構(gòu)訪問(wèn)屬性的方式。
來(lái)看看這是又是什么騷操作。
問(wèn)題
由于JS的動(dòng)態(tài)特性,對(duì)象可以具有多層不同的嵌套對(duì)象結(jié)構(gòu)。
通常,當(dāng)咱們處理以下這些對(duì)象時(shí):
- 獲取遠(yuǎn)程JSON數(shù)據(jù)
- 使用配置對(duì)象
- 有可選屬性
雖然JS為對(duì)象支持不同層次數(shù)據(jù)結(jié)構(gòu),但是在訪問(wèn)此類對(duì)象的屬性時(shí),復(fù)雜性也隨著增加。
1.bigObject可以在運(yùn)行時(shí)擁有不同的屬性集
// 嵌套版本
const bigObject = {
// ...
prop1: {
//...
prop2: {
// ...
value: 'Some value'
}
}
};
// 簡(jiǎn)單版本
const bigObject = {
// ...
prop1: {
// Nothing here
}
};因此,必須手動(dòng)檢查屬性是否存在
if (bigObject &&
bigObject.prop1 != null &&
bigObject.prop1.prop2 != null) {
let result = bigObject.prop1.prop2.value;
}這樣寫(xiě)太過(guò)冗長(zhǎng)了,最好避免寫(xiě)它。
咱們來(lái)看看可選鏈如何解決這個(gè)問(wèn)題,以減少冗余的代碼。
2. 易于深入訪問(wèn)屬性
設(shè)計(jì)一個(gè)保存電影信息的對(duì)象。 該對(duì)象包含必填title屬性,以及可選的director和actors。
movieSmall對(duì)象僅包含title,而movieFull包含完整的屬性集:
const movieSmall = {
title: 'Heat'
};
const movieFull = {
title: 'Blade Runner',
director: { name: 'Ridley Scott' },
actors: [{ name: 'Harrison Ford' }, { name: 'Rutger Hauer' }]
};寫(xiě)一個(gè)獲取director的函數(shù)。 請(qǐng)記住,director 可能不存在。
function getDirector(movie) {
if (movie.director != null) {
return movie.director.name;
}
}
getDirector(movieSmall); // => undefined
getDirector(movieFull); // => 'Ridley Scott'if(movie.director){...}條件用于驗(yàn)證是否定義了director屬性。 如果沒(méi)有這個(gè)預(yù)防措施,在訪問(wèn)movieSmall對(duì)象的director時(shí),JS會(huì)拋出TypeError: Cannot read property 'name' of undefined。
這種場(chǎng)景最適合使用可選鏈的功能了,如下所示,代碼將簡(jiǎn)潔很多。
function getDirector(movie) {
return movie.director?.name;
}
getDirector(movieSmall); // => undefined
getDirector(movieFull); // => 'Ridley Scott'在movie.director?.name表達(dá)式中可以找到?.可選的鏈接操作符。
在movieSmall中,沒(méi)有director屬性。 因此,movie.director?.name的的結(jié)果為undefined。 可選鏈運(yùn)算符可防止拋出 TypeError: Cannot read property 'name' of undefined。
簡(jiǎn)單地說(shuō),代碼片段:
let name = movie.director?.name;
等價(jià)于
let name;
if (movie.director != null) {
name = movie.director.name;
}?.通過(guò)減少兩行代碼簡(jiǎn)化getDirector()函數(shù),這就是為什么我喜歡可選鏈的原因。
2.1 數(shù)組項(xiàng)
可選的鏈功能可以做得更多。可以自由地在同一個(gè)表達(dá)式中使用多個(gè)可選的鏈接操作符,甚至可以使用它安全地訪問(wèn)數(shù)組項(xiàng)。
下一個(gè)任務(wù)是編寫(xiě)一個(gè)函數(shù),返回電影的actors中的name。
在movie對(duì)象中,actors數(shù)組可以是空的,甚至是缺失的,因此必須添加額外的條件來(lái)判空。
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屬性,并且此屬性至少有一個(gè)actor。
使用可選鏈接,同樣代碼也簡(jiǎn)潔了很了,如下:
function getLeadingActor(movie) {
return movie.actors?.[0]?.name;
}
getLeadingActor(movieSmall); // => undefined
getLeadingActor(movieFull); // => 'Harrison Ford'actors?. 確保actors屬性存在, [0]?.確保列表中存在第一個(gè)actor。
3.雙問(wèn)號(hào)操作符
一個(gè)名為nullish coalescing operator的新提議? 處理undefined或null,將它們默認(rèn)為特定值。
表達(dá)式變量?? 如果變量undefined或?yàn)?code>null,則默認(rèn)值為指定的值。
const noValue = undefined; const value = 'Hello'; noValue ?? 'Nothing'; // => 'Nothing' value ?? 'Nothing'; // => 'Hello'
接著使用??來(lái)優(yōu)化一下 getLeading()函數(shù),當(dāng)movie對(duì)象中沒(méi)有actor時(shí)返回“Unknown actor”
function getLeadingActor(movie) {
return movie.actors?.[0]?.name ?? 'Unknown actor';
}
getLeadingActor(movieSmall); // => 'Unknown actor'
getLeadingActor(movieFull); // => 'Harrison Ford'4. 可選鏈的三種形式
咱們可以使用以下3種形式的可選鏈。
第一種: object?.property 用于訪問(wèn)靜態(tài)屬性:
const object = null; object?.property; // => undefined
第二種:object?.[expression] 用于訪問(wèn)動(dòng)態(tài)屬性或數(shù)組項(xiàng):
// 其一 const object = null; const name = 'property'; object?.[name]; // => undefined // 其二 const array = null; array?.[0]; // => undefined
第三種:object?.([arg1, [arg2, ...]]) 執(zhí)行一個(gè)對(duì)象方法
const object = null;
object?.method('Some value'); // => undefined將這三種組合起來(lái)創(chuàng)建一個(gè)可選鏈:
const value = object.maybeUndefinedProp?.maybeNull()?.[propName];
5.短路:遇到 null/undefined 停止
可選鏈接運(yùn)算符的有趣之處在于,只要在左側(cè)leftHandSide?.rightHandSide遇到無(wú)效值,右側(cè)訪問(wèn)就會(huì)停止,這稱為短路。
看看例子:
const nothing = null; let index = 0; nothing?.[index++]; // => undefined index; // => 0
6. 何時(shí)使用可選鏈
不要急于使用可選的鏈操作符來(lái)訪問(wèn)任何類型的屬性:這會(huì)導(dǎo)致錯(cuò)誤的使用。
6.1訪問(wèn)潛在無(wú)效的屬性
?.一般使用在可能為空的屬性:maybeNullish?.prop。在確定屬性不為空的情況下,使用屬性訪問(wèn)器:.property或[propExpression]。
// 好
function logMovie(movie) {
console.log(movie.director?.name);
console.log(movie.title);
}
// 不好
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屬性的樣式對(duì)象。 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ù)正確地確定了元素是否有padding,但是對(duì)于每個(gè)屬性使用可選的鏈有點(diǎn)過(guò)于麻煩了。
更好的方法是使用對(duì)象擴(kuò)展操作符將padding對(duì)象默認(rèn)為零值
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這個(gè)就比可選鏈來(lái)的更簡(jiǎn)潔。
代碼部署后可能存在的BUG沒(méi)法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。
原文:https://dmitripavlutin.com/ja...
以上就是JS 可選鏈的三種形勢(shì)及好處詳解的詳細(xì)內(nèi)容,更多關(guān)于JS 可選鏈三種形勢(shì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Webpack?5新特性學(xué)習(xí)與性能優(yōu)化實(shí)踐
Webpack?5的新特性和改進(jìn)為前端開(kāi)發(fā)者提供了更強(qiáng)大、更高效的構(gòu)建工具,通過(guò)內(nèi)置的持久性緩存插件、優(yōu)化的默認(rèn)配置、Webpack?CLI的改進(jìn)等,Webpack?5使得構(gòu)建過(guò)程更加簡(jiǎn)化,性能更加優(yōu)越2024-05-05
Jjcarousellite 實(shí)現(xiàn)圖片列表滾動(dòng)的簡(jiǎn)單實(shí)例
這篇文章主要介紹了Jjcarousellite 實(shí)現(xiàn)圖片列表滾動(dòng)的簡(jiǎn)單實(shí)例,有需要的朋友可以參考一下2013-11-11
JS實(shí)現(xiàn)圖片預(yù)加載無(wú)需等待
網(wǎng)站開(kāi)發(fā)時(shí)經(jīng)常需要在某個(gè)頁(yè)面需要實(shí)現(xiàn)對(duì)大量圖片的瀏覽;用javascript來(lái)實(shí)現(xiàn)一個(gè)圖片瀏覽器,讓用戶無(wú)需等待過(guò)長(zhǎng)的時(shí)間就能看到其他圖片2012-12-12
JS實(shí)現(xiàn)簡(jiǎn)單路由器功能的方法
這篇文章主要介紹了JS實(shí)現(xiàn)簡(jiǎn)單路由器功能的方法,基于javascript模擬簡(jiǎn)單路由編碼的相關(guān)技巧,需要的朋友可以參考下2015-05-05
JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作示例
這篇文章主要介紹了JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作,結(jié)合實(shí)例形式分析了JavaScript邏輯判斷、流程控制、循環(huán)語(yǔ)句等相關(guān)操作技巧,需要的朋友可以參考下2020-01-01
element-ui 圖片壓縮上傳功能實(shí)現(xiàn)
這篇文章主要介紹了element-ui 圖片壓縮上傳功能實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-10-10
echarts學(xué)習(xí)之如何給餅圖中間添加文字
這篇文章主要介紹了echarts學(xué)習(xí)之如何給餅圖中間添加文字問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03

