JS判断对象自身为空
source link: https://blog.51cto.com/u_15997490/8924154
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
JS判断对象自身为空
精选 原创1. JSON.stringify
JSON.stringify
方法可以使对象序列化,转为相应的 JSON 格式。
const obj = {};
console.log(JSON.stringify(obj) === '{}') // true
缺点:如果存在 undefined
、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null
(出现在数组中时)。
如下示例:
const obj = {
a: undefined,
b: function() {},
c: Symbol()
}
console.log(JSON.stringify(obj) === '{}') // true
2. for in 配合 hasOwnProperty
使用 for in
对当前对象进行遍历:
const obj = {}
Object.prototype.a = 1
function isEmptyObj(obj) {
let flag = true
for (let o in obj) {
flag = false
break
}
return flag
}
console.log(isEmptyObj(obj)) // false
由于 for in
在进行对象遍历时,会遍历对象原型上的属性,而我们只希望得到其自身的属性,这时可以使用 hasOwnProperty
来实现,如下:
const obj = {}
Object.prototype.a = 1
function isEmptyObj(obj) {
let flag = true
for (let o in obj) {
if (obj.hasOwnProperty(o)) {
flag = false
break
}
}
return flag
}
console.log(isEmptyObj(obj)) // true
缺点:for in
不能遍历不可枚举的属性。
3. Object.keys
Object.keys
会返回对象自身可枚举属性组成的数组,而不会遍历原型上的属性。
const obj = {}
Object.prototype.a = 1
console.log(Object.keys(obj).length === 0) // true
缺点:Object.keys
和 for in
都只能遍历可枚举属性,不能遍历不可枚举的属性。
我们使用 Object.defineProperty
将属性 enumerable
设置为 false
来进行测试,示例如下:
const obj = {}
Object.defineProperty(obj, 'a', {
value: 1,
enumerable: false
})
console.log(obj.a) // 1
console.log(isEmptyObj(obj)) // true
console.log(Object.keys(obj).length === 0) // true
4. Object.getOwnPropertyNames
使用 Object.getOwnPropertyNames
可以得到对象自身的所有属性名组成的数组(包括不可枚举属性)。
const obj = {}
Object.defineProperty(obj, 'a', {
value: 1,
enumerable: false
})
console.log(Object.getOwnPropertyNames(obj)) // [ 'a' ]
缺点:不能获取 Symbol
值作为名称的属性,以上的 JSON.stringify
、for in
以及 Object.keys
方法也不能获取Symbol
值作为名称的属性,示例如下:
const a = Symbol()
const obj = {
[a]: 1
}
console.log(obj) // { [Symbol()]: 1 }
console.log(Object.getOwnPropertyNames(obj).length === 0) // true
console.log(JSON.stringify(obj) === '{}') // true
console.log(isEmptyObj(obj)) // true
console.log(Object.keys(obj).length === 0) // true
5. Object.getOwnPropertyNames 结合 Object.getOwnPropertySymbols
已知 Object.getOwnPropertyNames
唯一的缺点是不能获取 Symbol
值作为名称的属性,而 Object.getOwnPropertySymbols
只能获取由 Symbol
值作为名称的属性,两者相结合是不是就可以完美解决了。我们来简单测试一下:
const a = Symbol()
const obj1 = {
[a]: 1
}
const obj2 = {b: 2}
const obj3 = {}
Object.defineProperty(obj3, 'a', {
value: 1,
enumerable: false
})
const obj4 = {}
function getLength(obj) {
return Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj)).length
}
console.log(getLength(obj1) === 0) // false
console.log(getLength(obj2) === 0) // false
console.log(getLength(obj3) === 0) // false
console.log(getLength(obj4) === 0) // true
经过测试,上面这种方法的确可以解决,但是比较繁琐,那有没有更好的方法呢?答案是有的。
6. Reflect.ownKeys
Reflect.ownKeys
方法返回一个由目标对象自身的属性组成的数组,它的返回值等同于 Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))
,示例如下:
const a = Symbol()
const obj1 = {
[a]: 1
}
const obj2 = {b: 2}
const obj3 = {}
Object.defineProperty(obj3, 'a', {
value: 1,
enumerable: false
})
const obj4 = {}
console.log(Reflect.ownKeys(obj1).length === 0) // false
console.log(Reflect.ownKeys(obj2).length === 0) // false
console.log(Reflect.ownKeys(obj3).length === 0) // false
console.log(Reflect.ownKeys(obj4).length === 0) // true
判断一个对象是否为空时,使用 Reflect.ownKeys
方法最为完美。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK