检查属性存在性需据目标选择方法:查实例自有属性用object.hasown或hasownproperty.call;查原型链访问用'in'或reflect.has;查父类原型用'key' in parent.prototype;map/set等特殊结构须用专用has方法。

在类继承场景下检查属性是否存在,关键不是“怎么查”,而是“你想查什么”——是查实例自身的属性?还是包括父类原型上的方法或字段?不同目标对应不同方法,选错会导致逻辑错误或漏判。
查实例自身定义的属性(不含继承)
比如你用 class Child extends Parent,想确认 child 实例上是否显式设置了 status 字段(而非从父类继承或默认值),就该只看自有属性:
-
现代写法:用
Object.hasOwn(obj, 'key')—— 它不被原型污染,连Object.create(null)实例也能安全使用,且语义精准 -
兼容旧环境:用
Object.prototype.hasOwnProperty.call(obj, 'key')—— 避免子类意外覆盖了hasOwnProperty方法,比直接调用obj.hasOwnProperty('key')更可靠 - 别用
obj.key !== undefined—— 若父类构造器里写了this.status = undefined,这个判断就会误认为属性不存在
查能否通过点号访问到该属性(含父类原型链)
比如你在做配置兜底:child.methodName ?? parentDefault(),关心的是“调不调得通”,而不是“谁定义的”,那就该走原型链:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
首选
'methodName' in child—— 语法轻量、引擎优化好,能命中父类原型上定义的方法、getter,甚至toString这类继承来的基础方法 -
元编程场景用
Reflect.has(child, 'methodName')—— 和in行为一致,但更易集成进 Proxy 拦截逻辑,适合封装通用校验工具 - 注意:
in和Reflect.has都不区分可枚举性,Object.getOwnPropertyNames或getOwnPropertyDescriptor才用于精细控制
查父类原型上是否有某方法(排除实例自身重写)
有时你需要确认“父类是否提供了某个能力”,而不管子类有没有覆盖它。例如做运行时 API 兼容性检查:
- 用
'methodName' in Parent.prototype直接查父类原型 —— 简洁明确,不会被子类实例干扰 - 若需排除子类自己的同名属性,可组合判断:
!Object.hasOwn(child, 'methodName') && 'methodName' in Parent.prototype - 避免用
child.methodName !== undefined—— 子类若重写了该方法并返回undefined,就会掩盖父类的存在事实
特殊结构:Map/Set 实例要换方法
类继承中如果属性值是 Map 或 Set,别用 in 或 hasOwn 查键存在性:
-
map.has(key)和set.has(value)是专用接口,语义正确、性能最优 -
key in map检查的是 Map 对象自身的属性(如size),不是键值对 - 同理,数组索引存在性不能靠
index in arr(稀疏数组会误判),该用arr.hasOwnProperty(index)或更稳妥的Number.isInteger(index) && index >= 0 && index
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










