- Published on
Optional Chaining for JavaScript
- Authors
- Name
- Cypress Kuo
- @cypresskuo
今天來介紹一個,你不可不知的 ECMAScript 語法:Optional Chaining。
const user = { name: 'Cypress' }
const petName = user.pet?.name // does not throw error 👍
console.log(petName) // undefined
Property Chaining 的問題
Uncaught TypeError: Cannot read property 'XXX' of undefined / null
相信每一位寫 JavaScript 的工程師一定有遇過這個錯誤。 這個錯誤發生在沒有做好對 object 屬性檢查就直接對它進行操作。 常見的像是串接 api 時,返回了非預期的狀況。
const user = { name: 'Cypress' }
const countryCode = user.phone.code // 👎
// Uncaught TypeError: Cannot read property 'code' of undefined
解決方法
在還沒認識 Optional Chaining 之前,通常使用下面這兩種解決方法。
const user = { name: 'Cypress' }
const countryCode = user.phone && user.phone.code
console.log(countryCode) // undefined
這個寫法相當冗長,在多層的狀況下,程式碼不夠精鍊。
const foo = example.boo && example.boo.goo && example.boo.goo.verbose;
另一個就是用 Try-Catch
const user = { name: 'Cypress' }
let countryCode
try {
countryCode = user.phone.code
} catch (error) {
countryCode = undefined
}
這個方法也讓程式碼變得冗長,破壞了整體架構,還出現了不必要的 scope。
還有其他方法,像是使用 default value 加上 destructor, 或者用 FLOW
、PropTypes
之類的 type checker 都能防止錯誤發生。
Optional Chaining Operator
推薦的解法就是使用今天要介紹的 Optional Chaining
。
const user = { name: 'Cypress' }
const petName = user.pet?.name
// or
const expr = 'name'
const petName = user.pet?.[expr]
除了 object 之外,還可以用在 function 上。
const result = someInterface.customMethod?.(args)
如果 ?.
的前面是 undefined 或者 null 時,就會直接返回 undefined。 讓你可以不用再寫冗長的 checking code,也能避免掉取值的錯誤。
多層的狀況下也一樣好用
const foo = example.boo?.goo?.verbose; // undefined
心得後記
目前 optional chaining 已經進入 tc39 的 stage 4 了。 要嘗鮮可以在 Chrome Canary 上無痛使用。 但如果要在產品上使用,建議還是加上 babel plugin 來編譯語法。
第一次看到這個語法時,真的是相見恨晚。能用這麼簡潔的語法,何需再多寫一堆 checking code。 雖然 optional chaining 現在已經不是什麼新奇的語法了,還是很值得推薦給大家。
參考資料
Optional Chaining for JavaScript Optional chaining - JavaScript | MDN