instanceof 判断依赖原型链的物理结构是否真实完整,手动修改__proto__、置空原型链、错误设置子类prototype或跨realm环境均会导致失效,应正确继承并必要时用Symbol.hasInstance自定义逻辑。

要精准校验一个实例对象是否属于特定原型继承链,关键不是看“是不是用某个类 new 出来的”,而是确认它的原型链中**是否真实、完整、未被截断地包含目标构造函数的 prototype 对象**。只要引用匹配、链路通畅,instanceof 就能可靠返回 true。
确保原型链真实存在且未被破坏
instanceof 的判断完全依赖原型链的物理结构。以下操作会直接导致校验失效:
- 手动修改实例的
__proto__(如obj.__proto__ = {}),切断原有链路 - 用
Object.setPrototypeOf(obj, null)提前终止原型链 - 子类重写
prototype时没设置constructor,虽不立即影响 instanceof,但后续继承可能断裂 - 用
Child.prototype = new Parent()替代Object.create(Parent.prototype),把父类实例属性污染到原型上,间接干扰链路清晰性
正确构建和维持继承关系
让 instanceof 能跨层级识别,必须保证原型链逐级连通:
- 使用
class Child extends Parent:自动设置Child.prototype.__proto__ === Parent.prototype - 函数式继承时,用
Child.prototype = Object.create(Parent.prototype),再显式赋值Child.prototype.constructor = Child - 避免直接赋值
Child.prototype = {},这会丢失与父类的连接
注意执行上下文边界
instanceof 在跨 iframe 或不同 realm(如 Service Worker)中会失效,因为不同上下文中的 Array、Date 等构造函数是不同对象,它们的 prototype 引用不相等:
-
iframe.contentWindow.Array !== Array→arr instanceof Array在父窗口返回false - 此时应改用
Object.prototype.toString.call(arr) === '[object Array]' - 自定义类若需跨环境检测,必须将构造函数显式暴露到共享作用域,或改用
isPrototypeOf()配合已知原型对象
必要时接管判断逻辑
当默认原型链检查不满足需求(比如要支持伪多态、兼容旧数据格式),可在构造函数上定义 Symbol.hasInstance:
- 引擎执行
obj instanceof C时,优先调用C[Symbol.hasInstance](obj) - 例如让数字
42通过instanceof EvenNumber检测,只需在类中定义静态方法返回Number.isInteger(obj) && obj % 2 === 0 - 该方式绕过原型链,完全自定义语义,但需谨慎使用,避免破坏类型直觉

















