一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何用 Object.hasOwn 替代 hasOwnProperty 来规避原型链被篡改带来的安全风险

时间:2026-07-20 10:41:59 编辑:袖梨 来源:一聚教程网

Object.hasOwn(obj, key) 能彻底避开原型链被篡改风险,因其不依赖对象自身的hasOwnProperty方法或原型链,直接检查对象自身属性描述符,兼容null原型对象且不受方法重写影响。

直接用 Object.hasOwn(obj, key) 替代 obj.hasOwnProperty(key),就能彻底避开原型链被篡改的风险——它不依赖对象自身的 hasOwnProperty 方法,也不访问原型,只检查对象自身是否定义了该属性。

为什么 hasOwnProperty 会被“绕过”?

因为 hasOwnProperty 是从 Object.prototype 继承来的方法,一旦对象自己重写了这个方法,或原型链被污染,检测就失效:

  • 对象显式定义 hasOwnProperty: () => false,导致真实存在的属性被误判为不存在
  • 使用 Object.create(null) 创建的对象,根本没有 hasOwnProperty 方法,调用直接报错
  • 第三方数据不可控,可能已覆盖原型上的关键方法

Object.hasOwn 的三大优势

它专为解决上述问题而设计,是 ES2022 正式引入的推荐方案:

  • 不依赖原型:内部直接读取对象的自有属性描述符,完全绕过 Object.prototype
  • 兼容 null 原型对象:对 Object.create(null) 创建的对象也能安全调用
  • 不受方法重写影响:哪怕对象自己定义了恶意的 hasOwnPropertyObject.hasOwn 结果依然准确

典型替换写法对比

旧写法(有风险):

obj.hasOwnProperty('name') // ❌ 可能被重写、可能报错

新写法(推荐):

Object.hasOwn(obj, 'name') // ✅ 安全、简洁、语义明确

遇到需要兼容老环境的场景,可降级为:

Object.prototype.hasOwnProperty.call(obj, 'name')

但注意:这仍需确保 Object.prototype.hasOwnProperty 未被篡改,且写法更冗长。

实际应用中的注意事项

几个容易忽略但关键的点:

  • 它只判断属性是否存在,不管值是 undefinednull 还是其他任何值,只要键在对象自身上,就返回 true
  • 对数组也适用,比如 Object.hasOwn(arr, '2') 检查索引 2 是否被显式设置(而非仅因数组长度而“存在”)
  • 不支持 Symbol 作为字符串传入,必须传原始 Symbol 值:Object.hasOwn(obj, mySym),不能写成 'mySym'

热门栏目