检测对象自有属性应首选object.hasown(),语义准确、安全高效;兼容旧环境用object.prototype.hasownproperty.call();避免obj.hasownproperty()及obj.key!==undefined等错误写法。

检测对象是否存在自有属性,核心是确认“这个键是不是对象自己定义的”,而不是从原型链上继承来的。选错方法容易误判、性能差,甚至引发运行时错误。
现代首选:Object.hasOwn()
ES2022 引入的标准方法,语义最准确、调用最简洁、安全性最高:
- 直接写 Object.hasOwn(obj, 'key'),返回 true/false
- 不依赖对象原型,哪怕 obj 是
Object.create(null)或hasOwnProperty被覆盖,也能正常工作 - 能检测所有自有属性,包括不可枚举的(比如用
Object.defineProperty设置的enumerable: false属性) - 支持环境:Node.js 16.9+、Chrome 93+、Firefox 91+、Safari 16.4+;旧环境可用 polyfill 回退
兼容旧环境:Object.prototype.hasOwnProperty.call()
当项目仍需支持 IE 或早期 Node.js 时,这是最稳妥的降级方案:
- 必须写成 Object.prototype.hasOwnProperty.call(obj, 'key')
- 避免直接调用
obj.hasOwnProperty('key')——万一对象自身重写了该方法,就会出错 - 和
Object.hasOwn()行为一致:只查自有属性,包含不可枚举属性,不走原型链 - 比
Object.keys(obj).includes('key')快得多,也不生成临时数组
不推荐但常见:obj.hasOwnProperty('key')
写法简单,但存在隐患:
- 如果对象自身定义了同名方法(如
{ hasOwnProperty: () => false }),会调用到错误实现 - 若对象原型被污染(比如
Object.prototype.hasOwnProperty = null),整个调用会失败 - 现代代码应主动规避,优先用
Object.hasOwn()或Object.prototype.hasOwnProperty.call()
明确要避开的写法
以下方式看似能用,实则不是在检测“属性是否存在”,而是检测“值是否非 undefined”或“是否真值”:
-
obj.key !== undefined:属性存在但值为undefined时,误判为“不存在”;obj 为null或undefined时直接报错 -
obj.key != null:把0、false、''等假值也当作“不存在” -
Object.keys(obj).includes('key'):只能检测可枚举的自有属性,漏掉不可枚举属性(如JSON.stringify依赖的toJSON),还额外创建数组、遍历,性能差
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











