属性存在性检查必须先于类型检查,否则可能报错;应先用Object.hasOwn或in判断存在,再对属性值做typeof等类型验证,避免直接访问undefined/null引发错误。

检测对象属性存在性与类型检查不是一回事,但实际开发中常需联动判断——比如“属性存在且是字符串”或“方法存在且可调用”。关键在于先确认属性是否存在,再安全地检查其类型,避免因访问 undefined 或 null 而报错。
先查存在,再判类型:两步不能颠倒
直接对 obj.prop 做 typeof 或 instanceof 判断,前提是 prop 确实存在(或至少不会触发 TypeError)。否则可能抛出 Cannot read property 'xxx' of undefined。正确顺序是:
- 用 Object.hasOwn(obj, 'prop') 或 'prop' in obj 先确认结构层面的“有无”
- 再对 obj.prop 执行类型检查,如
typeof obj.prop === 'string'或Array.isArray(obj.prop) - 若属性可能为 null/undefined,且你关心的是“值是否可用”,可用
obj.prop != null && typeof obj.prop === 'number'组合判断
针对不同存在性语义,选匹配的类型检查路径
属性存在性有两类含义,对应不同的类型验证逻辑:
-
自有属性 + 类型校验:例如配置项必须由当前对象显式定义,且必须是函数。用
Object.hasOwn(obj, 'handler') && typeof obj.handler === 'function' -
可访问属性(含继承)+ 类型校验:例如检查对象是否具备
toString方法(来自原型),用'toString' in obj && typeof obj.toString === 'function' - 注意:
in和Object.hasOwn都不会触发 getter,而obj.prop访问会——如果类型检查需要读取值,且该属性有副作用 getter,需评估是否必要
避免在类型检查中隐含存在性假设
这些写法看似简洁,实则危险:
立即学习“Java免费学习笔记(深入)”;
-
typeof obj.prop === 'string'—— 若 obj 为 null 或 obj.prop 不存在,直接报错 -
obj.prop?.length—— 可链式安全访问,但无法区分“prop 不存在”和“prop 存在但为 undefined” -
obj.prop && typeof obj.prop === 'object'—— 把 falsy 值(如''、0、false)全过滤掉,语义偏离“类型检查”初衷
稳妥做法始终是分层:存在性 → 可访问性 → 类型 → 值有效性。
高频场景的推荐组合写法
实际编码中可封装复用,例如:
- 检查可选回调函数:
Object.hasOwn(config, 'onSuccess') && typeof config.onSuccess === 'function' - 检查内置方法是否可用(含继承):
'map' in Array.prototype && typeof [].map === 'function' - 检查某个不可枚举自有属性(如 Symbol.iterator):
Object.hasOwn(obj, Symbol.iterator) && typeof obj[Symbol.iterator] === 'function' - 兼容旧环境的安全写法:
Object.prototype.hasOwnProperty.call(obj, 'data') && Array.isArray(obj.data)


















