我发现有些初学的小伙伴在判断对象是否是空对象时用if(obj)或者是用if({}==={})。当你给他测试时,他才意识到问题。
判断对象是否为空的问题不仅在面试中经常被问到,在项目开发中也会经常使用到—比如我们在判断后端数据是否为空时所做的相应处理,以避免项目运行时产生问题。下面就说几种判断对象是否为空的方法。
有以下六种方式判断对象是否为空:
- 使用JSON.striginfy()
- 使用Object.keys()
- for…in循环
- Object.getOwnPropertyNames()
- Object.getOwnPropertyNames 和 Object.getOwnPropertySymbols
- Reflect.ownKeys
JSON.striginfy()
这是最常用的一个判断方法,该方法可以序列化对象并将其转换为相应的JSON字符串格式。
如果存在未定义属性值,或函数,Symbol值,在序列化过程中,它们将被忽略或转换为空。
所以不是很推荐这种方式,但如果能够确认不会出现以上这种情况的话,这种方法当然是最简单的一种方式。
Object.keys()
这也是会经常用到的方式。Object.keys()返回对象的属性名组成的一个数组,若长度为0 ,则为空对象。
例如,我们先给obj定义一个属性a,将其设置成可枚举类型,结果当然是false:
接下来我们再将enumerable 设置成false,属性a将不会统计出来,结果显示obj为空对象:
for in循环
for in循环需要和hasOwnProperty结合使用来判断对象是否为空。因为在for in循环时也会遍历原型上的属性,为了排除原型上的属性,所以使用hasOwnProperty。
这个方法同Object.keys一样,不能遍历非枚举的属性**。**演示如上…
Object.getOwnPropertyNames()
以上两种方法都不能获取非枚举属性,那有没有办法获取到非枚举属性呢?噔噔噔…就是这个Object.getOwnPropertyNames()!Object.getOwnPropertyNames()可以获取对象本身所有属性名称(包括非枚举属性)组成的数组。
似乎解决了前面的难题,但另一个难题又出现了----无法获取作为名称属性的Symbol值。上代码:
好吧,是所有的方法都识别不出symbol的值。在找到完美的解决方案之前我们坚持不懈。有没有既能非枚举属性,又能识别symbol的方法嘞?答案是有滴,请看下面的方法
Object.getOwnPropertyNames 和 Object.getOwnPropertySymbols
Object.getOwnPropertyNames唯一已知的缺点是无法获取以Symbol为名的属性。而Object.getOwnPropertySymbols 只能获取以Symbol为名的属性。所以这两个方法是相互补充,一拍即合。
嗯嗯嗯,经过上面的测试,完全符合我们的预期,perfect!似乎是有点麻烦😡 我们再得寸进尺一下,有没有既能识别非枚举属性,又能识别symbol值,又很简单的方法嘞?有…继续往下看
Reflect.ownKeys
其返回值也是数组。
总结
JSON.striginfy()
,Object.keys(),for…in循环,Object.getOwnPropertyNames()适合简单的判断,不能识别非枚举属性,不能识别symbol值。
Object.getOwnPropertyNames 和 Object.getOwnPropertySymbols和Reflect.ownKeys能识别非枚举属性,也能识别symbol值。