Y Write
无意中看到一篇判断空对象的博客,开头使用的就是 JSON.stringify 方法,只是看到这里,我便 Ctrl 接 W 一套丝滑连招。
JSON.stringify
JSON.stingify 会将对象序列化,如果传入的是一个空对象,那么显然是可以这么判断的。
JSON.stringify({}) // "{}"
JSON.stringify({
name: 'Tom'
}) // "{"name": "Tom"}"
看起来,JSON.stringify 是一个判断空对象的好方法,然而,事实真的如此吗?不妨看看下面的代码。
let obj = {
name: undefined
}
JSON.stringify(obj) // "{}"
JSON.stringify 会忽略掉值为 undefined 的 key,显然 obj 并不是一个空对象,即使它的 name 属性值是 undefined。如果你觉得这无伤大雅的话,我们接着往下看。
const symbol = Symbol()
let obj = {
[symbol]: 'hi',
say: function() {
console.log('hello world')
}
}
JSON.stringify(obj) // "{}"
JSON.stringify 直接把对象中的 方法 和 key 为 Symbol 的属性 也忽略了!此刻,你还认为 JSON.stringify 是一个判断空对象的好方法吗?
Object.keys,Object.values,Object.entries
这三个方法,我们说其中一个就行了。
let obj = {
name: 'Tom',
age: 30
}
Object.keys({}) // []
Object.keys(Obj) // ['name', 'age']
通过判断生成数组的长度可以判断 传入对象 是否为空对象,表面上看是这样的。
// 你是否能读懂这行代码
// 将 obj 的 name 属性变为 不可便遍历
Object.defineProperties(obj, {name: {enumerable: false}})
Object.keys(obj) // ['age']
因为 Object.keys,Object.values,Object.entries 是只能获取对象中的 可遍历 属性,当对象中的某些属性被设置为 不可遍历 后,自然也无法读取。当然,key 为 Symbol 的属性,用这三个方法也是的不到的。
Reflect.ownKeys
这个方法简单粗暴,获取所有属性名(包括 key 为 Symbol 的属性)。
obj[Symbol()] = 1
Object.defineProperties(obj, {name: {enumerable: false}})
Reflect.ownKeys({}) // []
Reflect.ownKeys(obj) // ['name', 'age', Symbol()]
后续应该会继续完善这篇博客。
2021/8/29,补充了对象中 key 为 Symbol 时对判断空对象的影响。