今天遇到判断是否为空对象的问题,发现还有很多细节待学习,下面我简单总结一下。
列出以下几种情况:
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