Object.hasOwn只判断属性是否为对象自身所有,不依赖也不读取属性描述符,直接查询引擎内部自有属性表,时间复杂度O(1),行为与hasOwnProperty一致但更底层、不可劫持。

Object.hasOwn 与属性描述符完全无关,它只回答一个问题:这个属性是不是对象自身的(own)?不看 configurable、不看 enumerable、不看 writable,也不触发 getter。
它不读取也不依赖属性描述符
Object.hasOwn 的实现直接查询对象内部的自有属性存在表(internal own property table),属于引擎底层的 O(1) 检查。它不会调用 Object.getOwnPropertyDescriptor,也不会解析属性的 descriptor 对象。
- 哪怕属性被设为
{ configurable: false, enumerable: false, writable: false },只要它是对象自身的,Object.hasOwn(obj, 'key')就返回true; - 一个不可枚举、不可配置、带 getter 的属性,
Object.hasOwn仍返回true—— 它不执行 getter,也不关心 getter 是否抛错; - 删除失败的不可配置属性(如严格模式下
delete obj.x报错),该属性依然存在,Object.hasOwn照样识别。
它和 hasOwnProperty 行为一致,但更底层
两者逻辑等价:都只判断“是否自有”,都不受属性特性的干扰。区别在于调用路径:
-
obj.hasOwnProperty('x')是原型方法调用,可能被覆盖或丢失; -
Object.hasOwn(obj, 'x')绕过原型链,直连引擎自有属性检查机制,不经过任何可劫持环节。
常见误判场景澄清
以下情况 Object.hasOwn 一定返回 false,和描述符无关:
- 属性来自原型链(哪怕原型上该属性是
configurable: false); - 传入非对象(
null、undefined、原始值),直接抛TypeError; - 属性名拼写错误,或动态计算后未实际定义在对象上。
对比其他 API 更能说明问题
Object.getOwnPropertyDescriptor(obj, 'x') 显式返回 descriptor 对象,你才能看到 configurable 等字段;Reflect.getOwnPropertyDescriptor 同理。而 Object.hasOwn 压根不提供这些信息 —— 它的设计目标就是轻量、确定、无副作用。
- 要查“有没有”,用
Object.hasOwn; - 要查“是什么样的”,用
Object.getOwnPropertyDescriptor; - 两者职责分离,不该混用。


















