最可靠的方法是 Object.keys(obj).length === 0,因其只检查自有可枚举属性,行为明确、兼容性好;其他方法如 JSON.stringify 或 for...in 存在忽略属性、原型污染或性能等问题。
JavaScript 中判断对象是否为空,最可靠的方法是 Object.keys(obj).length === 0。它只关心「自有可枚举属性」,行为明确、兼容性好、不易误判。
JSON.stringify(obj) === '{}'
这个写法看似直观,但有多个陷阱:
JSON.stringify() 会忽略 undefined、函数、Symbol 键,导致 {a: undefined, b() {}} 也被判为空toJSON() 方法(比如 Date 实例),结果完全不可控for...in 循环 + hasOwnProperty 能用吗?能用,但需谨慎。这是兼容老环境(如 IE8)时的备选方案:
function isEmpty(obj) {
if (obj == null || typeof obj !== 'object') return true;
for (let key in obj) {
if (obj.hasOwnProperty(key)) return false;
}
return true;
}
注意点:
obj.hasOwnProperty(key),否则会把原型链上可枚举属性(比如给 Object.prototype 挂了方法)也计入null 或非对象类型,得提前 guardObject.keys() 简洁安全这些写法在特定场景会出错,容易埋坑:
Object.entries(obj).length === 0:和 Object.keys() 行为基本一致,但多了一次数组构造开销,没必要Reflect.ownKeys(obj).length === 0:会包含 Symbol 键和不可枚举属性,比如 Object.defineProperty(obj, 'x', {value: 1, enumerable: false}) 会让它返回 false,而多数业务场景只关心可枚举属性!Object.keys(obj)[0]:靠取第一个键是否存在来判断,对空对象成立,但遇到 {'0': 'a'} 这种键名是字符串数字的对象,Object.keys()[0] 是 '0',取反为 false,误判为非空真正要注意的是:空对象判定从来不是纯技术问题,而是语义问题——你要判断的是“有没有可枚举自有属性”,还是“能不能被 JSON 安全序列化”,或是“原型链是否干净”。大多数时候,Object.keys(obj).lengt 就是那个平衡了准确性、可读性和兼容性的答案。
h === 0