检测对象是否“拥有”某方法应优先用in操作符(查整个原型链),其次用object.hasown()判断是否自有,再用typeof obj.method === 'function'确认可调用性。

要检测一个原型对象是否被某个对象“拥有”——即该对象的原型链中是否包含指定方法,本质是判断这个方法是否能在对象上被访问到。关键不在于“原型对象有没有这个方法”,而在于“对象调用时能否找到它”。常用且可靠的方式有三种,按推荐顺序说明:
用 in 操作符检查方法是否存在(含原型链)
这是最直接、覆盖最全的方式。它会沿着整个原型链查找,只要方法在对象自身或任意一级原型上定义(包括不可枚举属性),就返回 true。
-
'toString' in obj→ true(因为 Object.prototype 上有 toString) -
'map' in arr→ true(Array.prototype.map 存在) - 即使方法是不可枚举的(如通过
Object.defineProperty设置enumerable: false),in依然能捕获
用 hasOwnProperty() 或 Object.hasOwn() 判断是否自有
如果你只想确认方法是不是定义在对象**自身**上(而非继承来的),就用这两个方法:
-
obj.hasOwnProperty('customMethod')—— 传统写法,但若对象重写了hasOwnProperty就可能出错 -
Object.hasOwn(obj, 'customMethod')—— ES2022 新增,更安全,推荐优先使用 - 二者都只查对象自身,不看原型链;对值为
undefined的属性也准确返回 true
用 typeof obj.method === 'function' 验证可调用性
光存在不一定能用。有时属性存在但不是函数(比如被意外赋值为字符串)。加一层类型判断更稳妥:
-
typeof obj.someMethod === 'function'能同时确认:属性存在 + 类型是函数 - 注意:这会触发原型链查找,所以
obj可以是普通对象,也能正确识别继承来的方法 - 比单纯用
in多一重保障,适合真正要调用前的守卫
不建议依赖 constructor 或手动遍历 __proto__。前者易被篡改,后者非标准且已逐步弃用。用好 in、Object.hasOwn() 和 typeof 这三者,就能覆盖绝大多数场景。











