JavaScript中hasOwn与hasOwnProperty的兼容性对比

Object.hasOwn()是ES2022新增的静态方法,推荐用于安全判断对象自身属性;hasOwnProperty()是传统实例方法,存在被覆盖和null/undefined报错风险。

JavaScript 中没有 hasOwn 这个原生方法,它是 ES2022 新增的 Object.hasOwn(),而 hasOwnProperty() 是长期存在的实例方法。两者功能相似但设计定位、调用方式和兼容性差异明显。

Object.hasOwn():现代推荐方案

Object.hasOwn(obj, prop) 是标准静态方法,用于安全判断对象自身是否拥有指定属性(不查原型链)。它解决了 hasOwnProperty 被覆盖或缺失时的可靠性问题。

  • 支持所有现代浏览器(Chrome 93+、Firefox 92+、Safari 15.4+、Edge 93+)
  • Node.js 16.9+ 原生支持,16.0–16.8 需启用 --harmony-object-hasown 标志
  • 可直接用于 null/undefined 输入(返回 false),无需额外判空
  • 不依赖对象自身的 hasOwnProperty 方法,规避了被覆盖的风险

obj.hasOwnProperty(prop):传统但有隐患

这是每个对象从 Object.prototype 继承的实例方法,使用广泛但存在兼容性与健壮性短板。

  • 几乎所有 JavaScript 环境都支持(包括 IE6+)
  • 若目标对象的 hasOwnProperty 被重写或设为 undefined,调用会失败或返回错误结果
  • 不能直接用于 null 或 undefined(会抛出 TypeError)
  • 需兜底处理:常写作 Object.prototype.hasOwnProperty.call(obj, prop) 才真正安全

兼容性应对策略

若需支持老旧环境(如 IE 或 Node.js Object.hasOwn。

  • 使用 polyfill:MDN 提供的轻量实现可无缝降级
  • 构建工具中可通过 Babel(配合 @babel/preset-env)自动按目标环境转换
  • 在 TypeScript 项目中,确保 lib 配置包含 es2022 或更高版本以获得类型支持

实际使用建议

新项目优先用 Object.hasOwn(obj, key);维护老项目且需兼容 IE 时,继续用 Object.prototype.hasOwnProperty.call(obj, key)

  • 避免直接调用 obj.hasOwnProperty(key) —— 即使看起来“能跑”,也隐含风险
  • ESLint 可配置 no-prototype-builtins 规则来拦截不安全调用
  • 注意:in 操作符检查的是自身 + 原型链,与两者均不同,勿混淆

© 版权声明
THE END
喜欢就支持一下吧
点赞8赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容