Object.hasOwn性能略优于hasOwnProperty,因其为静态方法、无需原型链查找且避免覆盖风险;而hasOwnProperty在原型链异常或被覆盖时可能降级甚至报错,in最快但语义不同,Object.keys().includes()性能最差。

两者性能差异极小,日常开发中几乎感知不到——Object.hasOwn在现代引擎(如 V8)中做了内建优化,实际执行速度略快或持平;而hasOwnProperty虽经多年优化也很高效,但存在潜在运行时开销。
底层调用路径更直接
Object.hasOwn 是静态方法,引擎可直接绑定到原始实现,不经过目标对象的原型链查找或属性访问;而 obj.hasOwnProperty() 需先从 obj 查找该方法(哪怕它继承自 Object.prototype),若对象原型链深、或被篡改(如重定义 hasOwnProperty),可能触发额外解析或兜底逻辑。
无需防御性 call 就能安全执行
- 用
Object.prototype.hasOwnProperty.call(obj, key)虽能规避覆盖风险,但每次调用都涉及函数上下文切换和显式 call 绑定,带来轻微但可测的开销 - Object.hasOwn(obj, key) 一步到位,参数直接传入,V8 等引擎对其做了快速路径(fast path)特化,尤其在高频检测场景(如遍历、校验循环)中更稳定
不因对象结构异常而降级
遇到以下情况时,hasOwnProperty 可能被迫走慢路径甚至报错,间接拉低平均性能:
- 对象为
Object.create(null)—— 无原型,调用会 TypeError,必须提前判空或改用 call 写法 - 对象自身定义了
hasOwnProperty: null或hasOwnProperty: () => false—— 方法被覆盖,引擎需回退到通用函数调用机制 - null/undefined 输入 —— 直接抛错,中断执行流,后续逻辑无法复用缓存或批量处理
对比 in 操作符和 Object.keys().includes()
真正有明显性能差距的是其他方式:
-
in操作符:语法级支持,最快,但查的是整个原型链,语义不同 -
Object.keys(obj).includes(key):每次都要生成新数组、遍历字符串比较,大数据量下性能差一个数量级以上,应避免用于存在性检测


















