isPrototypeOf仅检测调用者是否在参数对象的原型链上,要求调用者为合法原型对象(非null/undefined/原始值),参数为真实对象实例,多层继承需逐级验证,跨realm场景比instanceof更可靠。

在复杂原型继承网格中,isPrototypeOf不是“万能层级探测器”,它只回答一个明确问题:**调用者是否出现在参数对象的原型链上**。它的价值在于精准、底层、不依赖构造函数名,但前提是严格遵循对象有效性与调用逻辑。
必须确保调用主体是合法原型对象
只有具备原型资格的对象才能作为isPrototypeOf的调用者——即非null、非undefined、非原始值(如"str"、42)、且本身是对象(包括普通对象、函数的prototype、Object.create()返回值等)。
- ✅ 安全:
Array.prototype.isPrototypeOf([])、myCustomProto.isPrototypeOf(instance)、Object.getPrototypeOf(obj).isPrototypeOf(obj) - ❌ 危险:
null.isPrototypeOf(x)(TypeError)、"abc".isPrototypeOf(x)(TypeError)、Object.create(null).isPrototypeOf(x)(false,因前者无原型链)
参数必须是真实对象实例,不能是原始值或空链
isPrototypeOf检测的是目标对象的整个[[Prototype]]链。若传入null或undefined,直接返回false;若传入字符串/数字等原始值,会尝试装箱为对象,但该临时包装体的原型链不包含用户定义的原型,结果恒为false。
- ✅ 有效:
MyBase.prototype.isPrototypeOf(new MySub())、{}.isPrototypeOf(Object.create({})) - ⚠️ 失效:
Date.prototype.isPrototypeOf("2023-01-01")→ false(字符串字面量不是Date实例) - ⚠️ 静默失败:
MyProto.prototype.isPrototypeOf(null)→ false(无链可查)
多层继承中需逐级验证,不可跳过中间原型
原型链是单向链表,isPrototypeOf只做存在性判断,不提供路径信息。在A→B→C→实例这样的链中,A.prototype.isPrototypeOf(instance)为true,不代表A直接是B的原型,只说明A在链上。若需确认完整层级结构,应配合Object.getPrototypeOf()手动遍历。
- 例如验证
instance是否经由Dog → Animal → LivingThing继承:LivingThing.prototype.isPrototypeOf(instance)&&Animal.prototype.isPrototypeOf(instance)&&Dog.prototype.isPrototypeOf(instance) - 避免误判:若仅检查顶层
LivingThing,可能掩盖Animal原型被意外替换的问题
跨realm或动态修改场景下,优先用isPrototypeOf而非instanceof
当涉及iframe、Web Worker或模块隔离环境时,不同上下文中的Array、Promise等构造函数互不相等,instanceof会失效,而isPrototypeOf只比对原型对象本身,只要原型引用一致(如通过共享模块导入),即可可靠工作。
- ✅ 可靠:
sharedArrayProto.isPrototypeOf(iframeArray)(前提是sharedArrayProto来自同一源模块) - ❌ 不可靠:
iframeArray instanceof Array(可能返回false) - 注意:
Object.create(null)创建的对象无Object.prototype,所有.isPrototypeOf()调用都返回false,需单独处理

















