在 JavaScript 中,可以通过多种方法判断一个对象自身是否为空(即没有自身的可枚举属性)。以下是一些常用的方法:
判断对象是否为空的方式
-
使用
Object.keys():Object.keys()方法返回一个对象自身的可枚举属性名的数组,如果数组长度为 0,则对象为空。function isEmpty(obj) { return Object.keys(obj).length === 0; } -
使用
Object.getOwnPropertyNames():Object.getOwnPropertyNames()返回一个对象自身的所有属性名(包括不可枚举属性)。如果返回的数组长度为 0,则对象为空。function isEmpty(obj) { return Object.getOwnPropertyNames(obj).length === 0; } -
使用
JSON.stringify(): 可以将对象序列化成 JSON 字符串,如果结果是{},则对象为空。function isEmpty(obj) { return JSON.stringify(obj) === '{}'; } -
使用
for...in循环: 如果使用for...in循环遍历对象的属性,如果可以遍历到属性,就说明对象不为空。function isEmpty(obj) { for (let key in obj) { if (obj.hasOwnProperty(key)) { return false; } } return true; } -
使用
Reflect.ownKeys():Reflect.ownKeys()方法返回一个包含对象自身所有属性的数组,包括字符串和符号。如果长度为 0,则对象为空。function isEmpty(obj) { return Reflect.ownKeys(obj).length === 0; }
各自优缺点
-
使用
Object.keys()- 优点:简单易懂,易于实现,只考虑可枚举属性。
- 缺点:如果对象上有不可枚举的属性,这些属性不会被计入(不能获取
Symbol值作为名称的属性,以上的JSON.stringify、for in以及Object.keys方法也不能获取Symbol值作为名称的属性)。 - 推荐使用度:适用于大多数场景。
-
使用
Object.getOwnPropertyNames()- 优点:返回对象的所有自有属性,包括不可枚举的属性。
- 缺点:如果对象原型链上有属性,这些属性不会被计入(
Object.getOwnPropertyNames唯一的缺点是不能获取Symbol值作为名称的属性,而Object.getOwnPropertySymbols只能获取由Symbol值作为名称的属性)。 - 推荐使用度:适合需要考虑不可枚举属性的场合。
-
使用
JSON.stringify()- 优点:直观,使用字符串表示法。
- 缺点:性能较低,因为需要将对象转换为字符串。如果对象中包含循环引用,可能会抛出异常。如果存在
undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成null(出现在数组中时) - 推荐使用度:不推荐用于性能敏感的场合。
-
使用
for...in循环- 优点:可以检测到所有可枚举的自有属性。
- 缺点:如果没有
hasOwnProperty的检查,可能会误判属性来自原型链(不能遍历不可枚举的属性)。 - 推荐使用度:在需要处理可枚举属性时可用,注意添加
hasOwnProperty检查。
-
使用
Reflect.ownKeys()- 优点:返回对象的所有自有属性,包括符号属性,适用范围广且全面。
- 缺点:与
Object.getOwnPropertyNames()类似,无法检查原型链上的属性。 - 推荐使用度:在需要确认所有自有属性存在时,推荐使用。
推荐使用的方法
对于一般用途,推荐 Object.keys() 方法,代码简洁,易于理解,而且在大多数情况下能够满足需求。如果你需要考虑不可枚举属性,建议使用 Object.getOwnPropertyNames() 。如果需要考虑符号属性,使用 Reflect.ownKeys() 是较好的选择。
总结来说,如果需求不复杂, Object.keys() 是最为稳妥和常用的方式,使用 Reflect.ownKeys 方法最为完美