instanceof 判定对象原型链是否包含指定构造函数的 prototype,而非实际类型;它沿 proto 查找是否严格等于 Ctor.prototype,继承链自然生效,但跨 iframe、原型篡改或原始值会导致失效,推荐用 Object.prototype.toString.call() 等更稳健方案。

instanceof 判定的是对象的原型链是否包含指定构造函数的 prototype,不是“类型”本身,而是“是否由该构造函数(或其继承链)创建并保持原型链接”。
核心机制:沿原型链向上查找
当执行 obj instanceof Ctor 时,JavaScript 引擎会:
- 从
obj.__proto__开始,逐级向上遍历原型链 - 检查每一层是否严格等于
Ctor.prototype - 找到则返回
true;直到原型为null仍未找到,返回false
继承关系中自然生效
只要子类正确继承父类(如通过 class B extends A 或 Object.setPrototypeOf(Sub.prototype, Super.prototype)),实例就能同时通过多级判定:
-
new Child() instanceof Child→true -
new Child() instanceof Parent→true(因Child.prototype链向Parent.prototype) -
new Child() instanceof Object→true(因所有对象最终继承自Object)
常见失效场景与原因
以下情况会导致预期外的 false:
-
跨 iframe/window:不同全局环境中的
Array不是同一个构造函数,iframe.contentWindow.Array !== Array -
原型被重写且未修复 constructor:若
Ctor.prototype = {}后未设constructor: Ctor,不影响 instanceof,但可能干扰其他逻辑 -
手动篡改 __proto__:如
obj.__proto__ = null或指向无关对象,直接切断继承链 -
原始值参与判断:
"abc" instanceof String恒为false,因字面量不是对象,不走原型链
更稳妥的替代方案
当需要稳定识别内置对象种类(尤其在跨环境、防污染或处理字面量时),推荐使用:
-
Object.prototype.toString.call(x):返回"[object Array]"等标准字符串,不依赖原型链 -
Array.isArray()、Number.isNaN()等专用方法:语义明确、兼容性好 - 对自定义类,确保
Symbol.toStringTag正确设置,可使toString.call()返回自定义标识

















