今天遇到判斷是否為空對象的問題,發現還有很多細節待學習,下面我簡單總結一下。
列出以下幾種情況:
1 let obj = {} 2 3 let obj1 = { 4 name: "jack" 5 } 6 7 let obj2 = { 8 [Symbol("name")]: "jack", 9 } 10 11 let obj3 = Object.defineProperty({}, "name", { 12 value: "john", 13 enumerable: false // 不可枚舉 14 })
方法一: 利用 for...in 循環
1 function isEmpty(obj) { 2 for (let i in Object.keys(obj)) { 3 return false // 進入循環即不為空 4 } 5 return true 6 } 7 console.log(isEmpty(obj)) // true 8 console.log(isEmpty(obj1)) // false 9 console.log(isEmpty(obj2)) // true 10 console.log(isEmpty(obj3)) // true
方法二:利用JSON.stringify()轉化為字符串
1 let isEmpty = (obj) => (JSON.stringify(obj) === '{}') ? true : false 2 3 console.log(isEmpty(obj)) // true 4 console.log(isEmpty(obj1)) // false 5 console.log(isEmpty(obj2)) // true 6 console.log(isEmpty(obj3)) // true
方法三: 使用Object.keys()將取出對象中的鍵名,再判斷長度
1 let isEmpty = (obj) => (Object.keys(obj).length === 0) ? true : false 2 3 console.log(isEmpty(obj)) // true 4 console.log(isEmpty(obj1)) // false 5 console.log(isEmpty(obj2)) // true 6 console.log(isEmpty(obj3)) // true
由此可見,以上三種方法不能判斷對象中的不可枚舉屬性。
如果對象中含有不可枚舉屬性,我們又需要找出這些屬性,就可以使用 Object.getOwnPropertyNames() 和 Object.getOwnPropertySymbols() 這兩個API。
Object.getOwnPropertyNames() 返回對象中的所有屬性(不包括symbol)
Object.getOwnPropertySymbols() 只返回對象中的symbol屬性
所以我們可以結合它們:
1 function isEmpty(obj) { 2 return !Object.getOwnPropertyNames(obj).length && !Object.getOwnPropertySymbols(obj).length 3 } 4 5 console.log(isEmpty(obj)) // true 6 console.log(isEmpty(obj1)) // false 7 console.log(isEmpty(obj2)) // false 8 console.log(isEmpty(obj3)) // false