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