Published on

Optional Chaining for JavaScript

Authors

今天來介紹一個,你不可不知的 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, 或者用 FLOWPropTypes 之類的 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