手写instanceof的核心是沿对象原型链向上查找right.prototype:先校验right为函数且有prototype,left非null/undefined且为对象;再用object.getprototypeof逐级比对,相等则返回true,至null未找到则返回false。

要手写实现一个支持多级原型链递归查找的 instanceof 算法,核心是模拟 JavaScript 原生 instanceof 的行为:检查左侧对象的原型链上是否**存在右侧构造函数的 prototype 对象**。
理解 instanceof 的本质逻辑
原生 a instanceof B 并不是在比构造函数名或做类型字符串判断,而是:
- 从
a.__proto__开始,沿着原型链向上逐级查找; - 只要某一级(包括
a.__proto__、a.__proto__.__proto__、…)严格等于B.prototype,就返回true; - 查到
null还没找到,返回false; - 右侧必须是函数(否则原生会抛
TypeError),且必须有.prototype属性。
手写实现(兼容多级、不依赖 for...in 或 Object.getPrototypeOf)
下面是一个简洁、健壮的手写版本:
function myInstanceof(left, right) {
// 1. 右侧必须是函数且有 prototype
if (typeof right !== 'function' || !right.prototype) {
throw new TypeError('Right-hand side of instanceof is not callable');
}
// 2. 左侧必须是对象(null 除外,但 null instanceof X 恒为 false)
if (left === null || left === undefined) return false;
if (typeof left !== 'object' && typeof left !== 'function') return false;
// 3. 沿原型链向上查找
let proto = Object.getPrototypeOf(left);
while (proto !== null) {
if (proto === right.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}
✅ 支持任意深度原型链(如 A → B → C → ... → Object.prototype);
✅ 正确处理 null、原始值、非函数右操作数;
✅ 使用 Object.getPrototypeOf 而非 __proto__(更标准、可代理、兼容性好)。
为什么不能直接用 left.__proto__ === right.prototype?
因为原型链可能很长。例如:
class A {}
class B extends A {}
class C extends B {}
const c = new C();
// c instanceof A → true,但 c.__proto__ 是 C.prototype,不是 A.prototype
// 需要递归查:c.__proto__ → C.prototype
// c.__proto__.__proto__ → B.prototype
// c.__proto__.__proto__.__proto__ → A.prototype ✅
边界情况验证
几个关键测试用例:
-
myInstanceof([], Array)→ true -
myInstanceof({}, Date)→ false -
myInstanceof(new Date(), Object)→ true(Date.prototype.__proto__ === Object.prototype) -
myInstanceof(null, Object)→ false -
myInstanceof(42, Number)→ false(原始值不是对象) -
myInstanceof(Object.create(null), Object)→ false(原型链起点就是null,无Object.prototype)
这个实现贴合 ES 规范中 [[HasInstance]] 的语义,不复杂但容易忽略类型校验和 null 边界。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











