【JavaScript 筆記】我覺得最好理解的《 可選串連 optional chaining》
讓程式碼更簡潔
假設我們有個 API , response 後接過來的資料長以下這樣
const cafe = {
latte: {
sugar: 2,
caffeine: 4,
},
espresso: {
sugar: 3,
caffeine: 5,
},
};
今天我要取到屬性 espresso 下面 sugar 的值,我一開始或許會寫這樣
const cafeElement = cafe.espresso.sugar;
console.log(cafeElement); // 3
但今天假設資料是動態的, response 的結構會改變,導致 espresso 這個屬性消失在我們的資料中,我們上面寫的東西會發生什麼事情?會出錯
const cafe = {
latte: {
sugar: 2,
caffeine: 4,
}
};const cafeElement = cafe.espresso.sugar;
console.log(cafeElement); // TypeError: Cannot read property 'sugar' of undefined
我們為了避免這樣的情況會怎麼寫?
- 一開始我直接想到的會用 if/ else 來避免,若沒有 espresso 我不會出錯,若有 espresso 也能拿到資料
let cafeElement;if (cafe.espresso !== undefined) {
if (cafe.espresso.sugar !== undefined) {
cafeElement = cafe.espresso.sugar;
}
}console.log(cafeElement); // undefined
但此方式不夠好,多寫了很多行,也有人說不夠優雅
2. 讓我們用三元運算子 ?
或是邏輯運算子 &&
來避免
let cafeElement = cafe.espresso ? cafe.espresso.sugar : undefined;console.log(cafeElement); // undefined
或是
let cafeElement = cafe.espresso && cafe.espresso.sugar && cafe.espresso.sugar;console.log(cafeElement); // undefined
這樣寫也都不會報錯,但有人說重複寫屬性很多次,還是不夠優雅,如果更多層就要寫更長
3. 也就是今天的主角:用《 可選串連》 ?.
來避免,這樣的寫法變得更簡潔,如果有資料我能讀取,沒有那個屬性,我也不會接受到錯誤
let cafeElement = cafe.espresso?.sugar;
console.log(cafeElement); // undefined
但 ?.
到底在判斷什麼?我覺得此篇教學有幾個點講得很好
?.
检查左边部分是否为 null/undefined,如果不是则继续运算。
因為 cafe.espresso
是 undefined,所以會中斷,它就會停止運算並返回 undefined
我们会说如果一个属性既不是 null 也不是 undefined,那么它就“存在”
改一下例子,把 response 改成以下這樣
const cafe = {
latte: {
sugar: 2,
caffeine: 4,
},
espresso: {},
};
我們用原來一開始拿資料的方式來看看會不會出錯,如下,結果不會報錯,因為 cafe.espresso 是存在的,只是資料為空的物件,但今天 cafe.espresso 是 null
或是 undefined
,以下的寫法就會出錯
let cafeElement = cafe.espresso.sugar;
console.log(cafeElement); // undefined
注意:
- 不要過度使用可選串連,像是以下這樣過度使用,如果我確定 cafe 會存在,我就不用在 cafe 後面使用
?.
let cafeElement = cafe?.espresso?.sugar;
因此,若確定某個屬性一定存在,就不用可選串聯,若不確定,則可以使用
2. 你也可以搭配 《空值合併運算符 (??) 》來使用,沒錯,兩個問號,??
一樣是在檢查左邊是否為 null/undefined
,如果是,則回傳後面預設的值,這個值由你自己定義,所以用此方式來搭配的差別是若可選串聯中斷後你能回傳你預設的值
let cafeElement = cafe.espresso?.sugar ?? "no attribute";
console.log(cafeElement); // no attribute
結論:
有沒有發現怎麼寫法這麼多種,好麻煩,沒關西我也是,我也還在體會這些不同之處,在開發上要用哪個好,在這之前還是得先認識它們,再慢慢熟悉,不過我認為可選串連運算符 (?.)
與 空值合併運算符 (??)
視情況來使用,畢竟看起來真的很簡潔,好像可以變得很厲害 (?)