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