點燈坊

失くすものさえない今が強くなるチャンスよ

使用 propOr() 提供預設值取的 Object 的 Property

Sam Xiao's Avatar 2019-09-15

實務上我們常需要讀取 Object 的 Property,但我們並不確定 Object 是否有該 Property,最嚴謹的做法必須先檢查 Property 是否存在才能讀取,否則在 Runtime 可能會得到 Cannot read property xxx of undefined 的錯誤訊息。

Version

macOS Mojave 10.14.6
VS Code 1.38.1
Quokka 1.0.244
Ramda 0.26.1

ECMAScript

let propOr = val => name => obj => (obj[name] || val);

propOr('No name')('name')({}); // ?
propOr('No name')('name')({ name1: 'Sam' }); // ?
propOr('No name')('name')({ name: 'Sam' }); // ?

我們想讀取 object.name 的值,由於 ECMAScript 是 dynamic language,並不保證 object 具有 name property,若只是 let getName = obj => obj.name; ,只要傳入的 object 沒有 name property,在 runtime 就會出現 Cannot read property xxx of undefined 的錯誤訊息。

實作 propOr(),第一個參數傳入 default value,第二個參數傳入 property 名稱,第三個參數傳入 object,最後使用 || 對 property 做檢查,若為 falsy value 則回傳 default value。

propOr000

propOr()

import { propOr } from 'ramda';

propOr('No name')('name')({}); // ?
propOr('No name')('name')({ name1: 'Sam' }); // ?
propOr('No name')('name')({ name: 'Sam' }); // ?

事實上 Ramda 已經提供 propOr(),可直接使用。

propOr()
a → String → Object → a
針對 object 的 property 取值,若 property 不存在,則回傳 default value

a:若 property 不存在,則提供 default value 回傳

String:property 名稱

Object:data 為 object

a:回傳 property 的 value 或 default value

propOr() 寫法遠比使用 || 語意更清楚

propOr001

Conclusion

  • 由於 ECMAScript 是 dynamic language,因此很多都必須在 runtime 檢查
  • 若要讀取 object 的 property,對於 property 的檢查是必要的,因為無法確定該 object 是否有 property,建議使用 Ramda 的 propOr() 取代用 || 檢查,語意會更清楚
  • propOr() 只能抓一層 property,若要抓多層 property,要使用 pathOr()

Reference

Ramda, propOr()
Ramda, pathOr()