Crocks 之 propPath()
栏目: JavaScript · 发布时间: 5年前
内容简介:Ramda 的VS Code 1.34.0Quokka 1.0.216
Ramda 的 path()
可能回傳 undefined
,這也是常見 Bug 來源之一;而 Crocks 的 propPath()
則回傳 Maybe
,可確保 ECMAScript 不再回傳不預期結果。
Version
VS Code 1.34.0
Quokka 1.0.216
Ramda 0.26.1
Crocks 0.11.1
ECMAScript
let user = { userName: 'Sam', email: 'oomusou@gmail.com', address: { street: '111 E. West Rd.', city: 'Taipei', postalCode: '11101' } }; // fn :: Object -> String let fn = obj => obj.address.postalCode; console.log(fn(user));
user
為 nested object,若想取得 user.address.postalCode
,可直接使用 .
取得。
若傳入的 object 真的有 address
object 與 postalCode
property,則一切順利如預期
let user = { userName: 'Sam', email: 'oomusou@gmail.com', address: { street: '111 E. West Rd.', city: 'Taipei', _postalCode: '11101' } }; // fn :: Object -> String let fn = obj => obj.address.postalCode; console.log(fn(user));
若傳入 object 不存在 postalCode
property,則會回傳 undefined
,這就是常見 bug 來源。
let user = { userName: 'Sam', email: 'oomusou@gmail.com', address: { street: '111 E. West Rd.', city: 'Taipei', _postalCode: '11101' } }; // fn :: Object -> String let fn = obj => obj.address.postalCode || 'N/A'; console.log(fn(user));
常見的寫法會使用 ||
判斷,若 postalCode
不存在則顯示其他 string。
這種寫法雖然可行,但有幾點必須注意:
-
||
是利用 falsy value 判斷,undefined
固然是 falsy value,但 empty string 也是 falsy value,若需求是要顯示 empty string 的話,這種寫法就會誤判造成 bug - 要時時小心 property 可能不存在加上
||
判斷,常因為粗心而忘記使用||
造成 bug -
||
並非商業邏輯一部分,只是為了防止 property 不存在而已,因此將 code 變髒了
let user = { userName: 'Sam', email: 'oomusou@gmail.com', _address: { street: '111 E. West Rd.', city: 'Taipei', postalCode: '11101' } }; // fn :: Object -> String let fn = obj => obj.address.postalCode || 'N/A'; console.log(fn(user));
address
object 也可能不存在,因此使用 ||
判斷並不夠完整,依然產生 Cannot read property of XXX of undefined
的 run-time 錯誤。
let user = { userName: 'Sam', email: 'oomusou@gmail.com', _address: { street: '111 E. West Rd.', city: 'Taipei', _postalCode: '11101' } }; // fn :: Object -> String let fn = obj => (obj.address && obj.address.postalCode !== undefined) ? obj.address.postalCode : 'N/A'; console.log(fn(user));
最完整的判斷需同時加上 obj.address
與 obj.address.postalCode !== undefined
雙重判斷,若都成立才能使用 obj.address.postalCode
取值,否則都回傳 N/A
。
這種寫法雖然可行,但有幾點必須注意:
- 若 nested object 很深,則判斷會很驚人
- 必須很小心的每一層都判斷,常因為粗心而造成 bug
- 這些判斷並非商業邏輯的一部分,只是為了防止 property 不存在而已,因此將 code 變髒了
Ramda
import { path } from 'ramda'; let user = { userName: 'Sam', email: 'oomusou@gmail.com', _address: { street: '111 E. West Rd.', city: 'Taipei', _postalCode: '11101' } }; // fn :: Object -> String let fn = path([ 'address', 'postalCode' ]); console.log(fn(user));
path()
[Idx] -> {a} -> a | Undefined
Idx = String | Int
針對 nested object 取得其 property 值
若 property 找不到, path()
會回傳 undefined
,所以儘管使用了 Ramda 的 path()
,問題依舊沒解決,一樣是 undefined
。
Crocks
import { propPath } from 'crocks'; let user = { userName: 'Sam', email: 'oomusou@gmail.com', address: { street: '111 E. West Rd.', city: 'Taipei', postalCode: '11101' } }; // fn :: Object -> Maybe String let fn = propPath([ 'address', 'postalCode' ]); console.log(fn(user).option('N/A'));
Crocks 提供了 propPath()
,用法與 Ramda 的 path()
完全相同,但回傳的是 Maybe
。
propPath()
Foldable f => f (String | Integer) -> a -> Maybe b
針對 nested object 取得其 property 值,但回傳為 Maybe
f (String | Integer)
:以 array 傳入 property
a
:data 為 object 或 array
Maybe b
:回傳 object 的 value 或 array 的 element,但會包成 Maybe
由於 propPath()
回傳為 Maybe
,需使用 option()
轉回 string,並順便處理 undefined
。
使用了 Maybe
後,我們發現:
- 無論 nested object 有多深,我們都不須擔心 object 或 property 不存在;也不用擔心 falsy value 判斷有潛在 bug
- 不用擔心粗心而造成 bug,只要記得 nested object 使用
propPath()
即可 - Function 內不再有判斷 property 存在與否邏輯,只剩下原本商業邏輯,非常乾淨
- 因為
Maybe
一定要透過option()
取出,不會忘記處理undefined
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
尽在双11:阿里巴巴技术演进与超越
阿里巴巴集团双11技术团队 / 电子工业出版社 / 2017-4 / 79
“双 11”,诞生于杭州,成长于阿里,风行于互联网,成就于新经济,贡献于全世界。 从 2009 年淘宝商城起,双 11 已历经八年。每年的双 11 既是当年的结束,又是走向未来的起点。技术的突破创新,商业模式的更替交互,推动着双 11 迈步向前。 《尽在双11——阿里巴巴技术演进与超越》是迄今唯一由阿里巴巴集团官方出品、全面阐述双 11 八年以来在技术和商业上演进和创新历程的书籍。内容......一起来看看 《尽在双11:阿里巴巴技术演进与超越》 这本书的介绍吧!