instanceof 的核心机制是沿对象原型链查找是否严格等于构造函数的 prototype 对象;它只比较引用而非内容,可被 symbol.hasinstance 自定义。

instanceof 的核心机制,是沿着左侧操作数(对象)的原型链,逐级向上查找,看能否找到右侧构造函数的 prototype 对象。
查找过程:从对象的 __proto__ 开始向上遍历
当执行 obj instanceof Constructor 时,JavaScript 引擎会:
- 获取
Constructor.prototype的引用(注意:是那个对象本身,不是它的属性) - 从
obj.__proto__开始,反复取__proto__,直到遇到null - 在每一步中,检查当前原型对象是否**严格等于**
Constructor.prototype - 只要某一层相等,就返回
true;查到尽头都没匹配,返回false
关键细节:只比对象引用,不比内容或结构
它判断的是“是不是同一个对象”,而不是“长得像不像”或“有没有同名属性”:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 即使两个函数的
prototype对象有完全相同的属性和方法,只要不是同一个对象,instanceof就不会认 - 手动修改
obj.__proto__ = Constructor.prototype,就能让obj instanceof Constructor返回true - 如果重写了构造函数的
prototype(比如赋值为新对象),之前用new创建的实例可能不再满足instanceof
常见误区:不是查找“构造函数名”或“类名”
instanceof 完全不关心函数的名字、是否用了 class 语法、或者对象内部有没有 constructor 属性:
-
let a = {}; console.log(a instanceof Object); // true—— 因为a.__proto__ === Object.prototype -
let b = []; console.log(b instanceof Array); // true—— 因为b.__proto__ === Array.prototype -
let c = new Date(); console.log(c instanceof Date); // true—— 同理 - 但
let d = { constructor: Date }; console.log(d instanceof Date); // false——constructor属性只是普通属性,不影响原型链查找
可被代理或覆盖:Symbol.hasInstance
构造函数可以自定义 instanceof 的行为,通过设置静态方法 [Symbol.hasInstance](obj):
- 如果存在该方法,引擎会直接调用它,并把结果作为
instanceof的返回值 - 这使得
instanceof不再依赖默认的原型链查找逻辑 - 例如:
Array[Symbol.hasInstance] = () => true;会让任意值instanceof Array都返回true(不推荐,仅说明机制)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










