hasOwnProperty 通常很快,因不遍历原型链、仅查对象内部属性表,且被主流引擎内联优化;但对象覆盖该方法或使用 Object.create(null) 会降级;推荐用 Object.hasOwn 或 Object.prototype.hasOwnProperty.call 替代。

检测对象自有属性,hasOwnProperty 在现代引擎中是 O(1) 平均查找,性能优秀,但它的实际表现取决于调用方式和运行环境。
为什么 hasOwnProperty 通常很快
它不遍历原型链,只查对象内部的属性表,V8、SpiderMonkey 等引擎对其做了内联优化和快速路径处理。对普通对象来说,开销几乎可忽略。
- 比
Object.keys(obj).includes(key)快一个数量级以上——后者要构造数组、遍历字符串 - 比
'key' in obj更轻量,因无需沿原型链逐层查找 - 支持 Symbol 类型键名,且能检测不可枚举属性(如通过
Object.defineProperty设置的)
影响性能的隐患场景
看似快,但某些写法会绕过引擎优化,甚至触发降级路径:
- 直接调用
obj.hasOwnProperty('key'):若对象自身覆盖了该方法(如{ hasOwnProperty: () => false }),引擎无法内联,转为通用调用,性能下降 - 对象来自
Object.create(null):没有hasOwnProperty方法,调用即报错,无法进入任何优化路径 - 高频调用中混用不同键名或动态 key:可能干扰内联缓存(IC)命中,导致 LoadIC_Miss 频发
更稳更快的替代方案
不是抛弃 hasOwnProperty,而是用更可靠的方式调用它,或升级到语义等价但更健壮的新标准:
立即学习“Java免费学习笔记(深入)”;
-
Object.prototype.hasOwnProperty.call(obj, 'key'):绕过对象自身查找,强制使用原始方法,兼容create(null),且仍享受引擎对 call + 原生方法的优化 -
Object.hasOwn(obj, 'key'):ES2022 标准方法,静态调用、无原型依赖、语法简洁;现代环境(Node.js 16.9+、Chrome 93+ 等)中性能与优化程度持平甚至略优 - 避免回退到
Object.keys().includes():它生成临时数组、漏不可枚举属性、无视原型链,纯属语义错配+性能拖累
真实性能建议
不必为单次检测微优化,但对高频逻辑(如渲染循环、数据校验、Proxy 拦截器)需注意:
- 统一使用
Object.hasOwn(新项目)或Object.prototype.hasOwnProperty.call(需兼容旧环境) - 避免在热路径中拼接 key 或使用变量 key,尽量保持键名为字面量常量
- 若原型链深度超过 10 层且频繁用
in,才需考虑扁平化结构——hasOwnProperty类方法本身不受此影响



















