instanceof 检测对象原型链中是否严格等于构造函数的 prototype 对象;需避免重写 prototype、注意箭头函数无 prototype、跨 iframe 时构造函数不等价。

instanceof 检测的是对象的原型链中是否**存在构造函数的 prototype 属性所指向的对象**,不是简单比对构造函数名,也不是只查直接原型。要精准判断,关键在于理解其底层逻辑并避开常见陷阱。
核心原理:沿着 __proto__ 向上查找
当执行 a instanceof B 时,JavaScript 引擎会:
- 获取
B.prototype的引用(注意:是这个对象本身,不是它的值或副本) - 从
a.__proto__开始,沿原型链逐级向上比较(===严格相等) - 只要某一级
__proto__与B.prototype是同一个对象,就返回true - 查到
null还没匹配,返回false
必须确保 prototype 未被意外替换
如果构造函数的 prototype 被整个赋值覆盖(如 B.prototype = {}),旧实例将不再满足 instanceof B,因为它们的原型链里存的是原来的 prototype 对象。
- ✅ 正确扩展:用
Object.assign(B.prototype, { method() {} }) - ❌ 危险操作:直接
B.prototype = { method() {} }(会切断已有实例的关联) - ⚠️ 补救方式:若已重写,可用
Object.setPrototypeOf(instance, B.prototype)修复单个实例
注意箭头函数、字面量和内置类型的行为差异
箭头函数没有 prototype,不能用 instanceof 检测;而数组、正则等字面量创建的对象,其原型链终点仍是对应内置构造函数的 prototype:
-
[1,2] instanceof Array→true(原型链含Array.prototype) -
/abc/ instanceof RegExp→true -
const fn = () => {};→fn instanceof Function为true(箭头函数仍是Function实例) -
fn instanceof Object也为true(因Function.prototype.__proto__ === Object.prototype)
跨 iframe 场景需用同源构造函数
不同 iframe 中定义的 Array 是不同函数对象,各自 prototype 也不相等。因此:
iframe.contentWindow.Array !== Array-
arrFromIframe instanceof Array→false(即使 arrFromIframe 是数组) - 安全检测应改用
Array.isArray(arrFromIframe)或Object.prototype.toString.call(arrFromIframe) === '[object Array]'











