被Lodash的方法騙了好幾年,今天終于踩了大坑了!
背景
我們項(xiàng)目中有一處業(yè)務(wù)代碼,需要根據(jù)不同的條件,對(duì)某個(gè)對(duì)象進(jìn)行屬性的刪除,大概代碼如下:
接著需要判斷這個(gè)對(duì)象是否為空,為空的話就去執(zhí)行另一個(gè)很重要的邏輯,這里判斷對(duì)象為空,我們選擇了lodash的isEmpty方法:
出問(wèn)題了
然后就出事了,上線后發(fā)現(xiàn)有 BUG ,定位問(wèn)題之后,發(fā)現(xiàn)就是明明對(duì)象不為空,然后isEmpty還是把這個(gè)對(duì)象判為空了,然后去執(zhí)行了接下來(lái)的邏輯,導(dǎo)致出現(xiàn) BUG
然后我就去看了一下 isEmpty的源碼,總算是發(fā)現(xiàn)問(wèn)題了!
可以看到最后一個(gè)環(huán)節(jié),isEmpty 在判斷對(duì)象是否為空的時(shí)候,用了for in + hasOwnProperty去判斷某一個(gè)屬性是否存在對(duì)象中,只要有一個(gè)存在,那么這個(gè)對(duì)象就不為空!
誒!那好像也沒(méi)啥問(wèn)題???但是我突然想到,那這個(gè)for in能遍歷出 Symbol 類型的屬性嗎?于是我試了一下,發(fā)現(xiàn) for in 并不會(huì)遍歷 Symbol屬性。
這也嚴(yán)重了問(wèn)題出在lodash 的 isEmpty上,并且根本原因是 for in 并不會(huì)遍歷 Symbol屬性。
解決問(wèn)題
所以還是自己實(shí)現(xiàn)一個(gè)來(lái)解決這個(gè)問(wèn)題吧?。?!我們可以獲取到對(duì)象的屬性個(gè)數(shù),判斷屬性個(gè)數(shù)是否為0,為0那就是為空。
那可以用Object.keys嗎?他的作用就是可以把對(duì)象的屬性放到一個(gè)數(shù)組中,我們?cè)囋囍螅l(fā)現(xiàn)Object.keys并不會(huì)把Symbol屬性算進(jìn)去:
我們換一下Reflect.ownKeys試試,發(fā)現(xiàn)就完全可以了!?。?!
所以最終自己實(shí)現(xiàn)了一個(gè) isEmpty: