应使用 object.prototype.hasownproperty.call(obj, 'prop') 或 object.hasown(obj, 'prop') 替代 obj.hasownproperty(prop),以避免原型污染、方法覆盖或 object.create(null) 导致的报错与误判。

因为 hasOwnProperty 是对象实例上的方法,如果对象的原型链上重写了该方法,或对象本身没有继承自 Object.prototype(比如用 Object.create(null) 创建的对象),直接调用 obj.hasOwnProperty(prop) 就会出错或返回错误结果。
原型链污染或方法被覆盖时不可靠
当某个对象的 hasOwnProperty 被意外覆盖(例如 obj.hasOwnProperty = null 或指向其他函数),或者其原型链上存在同名属性时,直接调用会失效:
-
报错:若
hasOwnProperty被设为null或undefined,调用会触发TypeError -
误判:若原型上有自定义的
hasOwnProperty,可能返回非预期逻辑(比如始终返回true)
Object.create(null) 对象不继承该方法
用 Object.create(null) 创建的对象没有原型,因此根本不存在 hasOwnProperty 方法:
-
const obj = Object.create(null); obj.hasOwnProperty('x')→TypeError: obj.hasOwnProperty is not a function - 这类对象常用于哈希表、配置项等场景,直接调用必然失败
推荐替代写法:用 Object.prototype.hasOwnProperty.call()
绕过实例自身的方法,强制使用原生、可靠的实现:
-
Object.prototype.hasOwnProperty.call(obj, 'prop')—— 安全、通用、无依赖 - 也可简写为
{}.hasOwnProperty.call(obj, 'prop'),但前者语义更清晰 - TypeScript 或 ESLint 通常也会提示直接调用的风险,建议统一采用这种写法
现代替代方案:in 操作符 + hasOwn(ES2022+)
ES2022 引入了 Object.hasOwn(),是专为此场景设计的标准化方法:
-
Object.hasOwn(obj, 'prop')等价于安全版hasOwnProperty - 它不依赖对象原型,兼容
Object.create(null),且更易读 - 注意兼容性:Node.js ≥16.9 / Chrome ≥93 / Firefox ≥92+,旧环境需 polyfill 或回退











