JS28 判断对象是空对象
如何判断对象是空对象,总结了一下。
概述
一个空的对象{}
在JS中进行判断,显示为真值:
1 | var a = {}; |
所以要判断对象中是否含有属性,需要使用特殊的手段,不同情况下有不同的手段:
Reflect.ownKeys()
JSON.stringify
Object.keys
/Object.values
/Object.entries
Object.getOwnPropertyNames()
for...in
- 其他方法
这里判断对象是否是空对象,应该刨除原型链继承的影响,只观察对象自身是否含有任意属性值。
基于这个前提下,我认为可能Reflect.ownKeys()
是更恰当的方法。
遍历方法的区别
先来看一下各种遍历方法的区别:
自身属性 | 原型属性 | 可枚举属性 | 不可枚举属性 | Symbol属性 | |
---|---|---|---|---|---|
for...in |
√ | √ | √ | × | × |
Object.getOwnPropertyNames |
√ | × | √ | √ | × |
Object.keys |
√ | × | √ | × | × |
Relect.ownKeys |
√ | × | √ | √ | √ |
Reflect.ownKeys(target)
Relfect对象是ES6为操作对象提供的新API,它提供了许多针对对象的操作方法,其中ownKeys
用于返回对象的所有属性,基本等同于Object.getOwnPropertyNames
与Object.getOwnPropertySymbols
之和。
它与其他的遍历方法最大的不同就是,它会将对象中Symbol类型的属性名遍历出来,而其他的方法不会。
1 | function isEmpty(obj) { |
其他的方法都有着自己的局限性。
Object.keys()
Object.keys()
方法返回的数组中只包括自身可枚举的属性,不可枚举属性和Symbol属性都包括在返回结果中
Object.getOwnPropertyNames()
Object.getOwnPropertyNames()
返回的结果中包含自身可枚举和不可枚举的属性,但是不包含Symbol属性
它与Object.keys()
相比,返回结果增加了自身不可枚举的属性
for...in
利用for...in
对对象进行遍历时,会返回自身以及原型链上的可枚举属性,返回结果不包含Symbol属性
我们这里的前提是不考虑原型链继承而来的属性,所以即便不考虑Symbol属性,也需要通过hasOwnProperty
判断遍历的结果是继承自原型链还是属于自身的属性
JSON.stringify()
JSON.stringify()
方法可以将对象序列化为字符串,但是在序列化过程中会忽略方法属性和Symbol属性
1 | const a = { |
Lodash的isEmpty
方法
使用Lodash的isEmpty
判断对象是否是空对象时,对象如果被认为为空,那么他们没有自己的可枚举属性的对象。
它对字符串、数组、类数组对象也考虑在内了,如果这些对象长度为0
,就认为是空对象
对于Map和Set对象,如果其size
为0
,就认为是空对象
看一下它的源码:
1 | /** |
发现它使用的是for...in
来进行主要的判断,对Symbol属性也没有进行判断
1 | const key = Symbol(123); |