判断对象是否为空的最常用且推荐方式是object.keys(obj).length === 0,它仅检查自身可枚举属性,简洁高效、兼容性好;需严格判断时应结合getownpropertynames和getownpropertysymbols;json.stringify(obj) === "{}"和for...in+hasownproperty则各有适用场景与局限。

判断对象是否为空,是深拷贝前的重要前置步骤——它帮你避开对空对象做冗余递归,也避免在赋值逻辑中误判状态。准确与否,取决于你对“空”的定义和实际使用场景。
最常用且推荐:Object.keys(obj).length === 0
这是日常开发中最稳妥、高效的方式。它只检查对象自身的可枚举属性,不涉及原型链、Symbol 或不可枚举属性,覆盖绝大多数业务需求。
- ✅ 简洁清晰,性能好,ES6+环境原生支持
- ✅ 对普通字面量对象、Vue data 初始化对象、API 返回的纯数据对象都适用
- ❌ 不检测不可枚举属性(如 Object.defineProperty 设置的 enumerable: false)和 Symbol 属性
需要更严格判断时:结合 getOwnPropertyNames 和 getOwnPropertySymbols
如果你的对象可能含有不可枚举属性或 Symbol 键(比如某些库内部构造的对象),仅靠 Object.keys 就不够了。
- 用 Object.getOwnPropertyNames(obj).length === 0 检查所有自身属性名(含不可枚举)
- 再用 Object.getOwnPropertySymbols(obj).length === 0 检查 Symbol 类型键
- 两者同时为 true,才表示该对象真正“无任何自身属性”
慎用但偶有场景:JSON.stringify(obj) === "{}"
它依赖序列化结果,表面看简单,但存在明显局限:
- ❌ 遇到函数、undefined、Symbol、Date、RegExp、Map/Set 等会丢失或报错
- ❌ 会跳过不可枚举属性和原型链属性,但无法区分“真空”和“被过滤后的空”
- ⚠️ 仅适合结构简单、已知不含特殊值的纯数据对象,比如临时校验表单初始状态
兼容老环境或需遍历控制:for...in + hasOwnProperty
适用于需要兼容低版本运行时,或你想在判断过程中顺便做其他逻辑(如日志、类型预检)。
- 手动遍历,每遇到一个自身可枚举属性就返回 false
- 循环结束未触发 return,说明没找到,返回 true
- 注意必须配合 obj.hasOwnProperty(key),否则会把原型上的属性也误判进来











