instanceof 的判断结果完全取决于原型链中是否存在严格相等的 Constructor.prototype。它通过逐级查找 obj.__proto__ 是否与 Constructor.prototype 引用相同来判定,不依赖类型名、构造函数体或自动装箱,且跨 iframe 或原型链被篡改时均失效。

instanceof 的判断结果完全取决于原型链的结构和查找路径。它不是在比对类型名或构造函数本身,而是实实在在地沿着对象的 __proto__ 一级级向上检查,看是否能碰到右侧构造函数的 prototype 对象。
原型链决定 instanceof 的真假
一个对象 只有在其原型链中某一层恰好等于 Constructor.prototype 时,obj instanceof Constructor 才会返回 true。哪怕只差一层、多一层、或中间被篡改过,结果都会变。
- 数组
[1,2,3]的原型链是:Array.prototype → Object.prototype → null,所以[1,2,3] instanceof Array和instanceof Object都为 true - 若手动执行
arr.__proto__ = null,再查arr instanceof Array就变成 false —— 因为链断了,找不到Array.prototype - 若把
Person.prototype改成指向另一个对象(比如Object.prototype),那所有new Person()实例就不再属于Person的“血统”,instanceof Person全部失效
__proto__ 和 prototype 必须严格匹配
instanceof 不关心名字、不看构造函数体、也不自动转换类型。它只做一件事:引用相等判断(===)。这意味着:
-
obj.__proto__ === Constructor.prototype是核心条件,不是“相似”或“包含”,必须是同一个内存地址 - 跨 iframe 创建的对象,其
Array.prototype和当前环境的Array.prototype是两个不同对象,所以iframeArr instanceof Array返回 false - 基本类型(如字符串
'abc')没有__proto__,直接跳过查找,一律返回 false;不会像方法调用那样自动包装
继承关系必须靠原型链真实存在
子类要被识别为父类的实例,不能只靠 class extends 语法糖,关键在于 Sub.prototype.__proto__ 是否真指向 Super.prototype。
- 正确继承:
Student.prototype = Object.create(Person.prototype)→stu instanceof Person为 true - 错误写法:
Student.prototype = new Person()虽然也能工作,但会执行构造函数,可能带来副作用;更严重的是如果没修复constructor,不影响 instanceof,但语义混乱 - 若忘记设置继承:
Student.prototype = {},那stu instanceof Person就是 false,哪怕逻辑上你认为它“应该”是
手写实现暴露了全部细节
一个健壮的手写 myInstanceof 必须模拟 JS 引擎的真实行为:
- 先校验左侧是否为对象或函数(排除
null、数字、字符串等) - 再确保右侧是函数(否则没有
prototype属性) - 用
Object.getPrototypeOf()安全获取原型,避免直接读__proto__(已被标记为废弃) - 循环中逐层比较,直到原型为
null停止,不遗漏任何环节


















