instanceof的本质是沿左操作数的[[Prototype]]链向上查找是否匹配右操作数的prototype。手写实现需先校验左操作数为非null对象,再用Object.getPrototypeOf遍历原型链严格比较,正确处理原始值、null及箭头函数等边界情况。

instanceof 的本质是沿着左侧对象的 __proto__ 链向上查找,看能否找到右侧构造函数的 prototype 对象。手写实现的关键在于模拟这个原型链遍历过程,同时正确处理边界情况(如 null、undefined、原始值)。
核心逻辑:遍历原型链匹配 prototype
JavaScript 中每个对象都有内部属性 [[Prototype]](可通过 obj.__proto__ 或 Object.getPrototypeOf(obj) 访问),而函数有 prototype 属性(仅函数有,且仅用于被 new 调用时赋给实例的 [[Prototype]])。instanceof 就是不断取左操作数的 [[Prototype]],和右操作数的 prototype 严格相等比较。
- 从
left.__proto__开始查起(不是从 left 本身开始) - 每次比较
current === right.prototype - 若相等,返回
true;若到达原型链顶端(null),返回false - 若左操作数不是对象(如字符串、数字字面量),直接返回
false(因为原始值没有原型链)
手写实现代码(含健壮性处理)
以下是一个符合规范的行为实现:
<font color="#0066cc">function</font> myInstanceof(left, right) {
<font color="#0066cc">if</font> (typeof left !== <font color="#dd2200">'object'</font> || left === <font color="#0066cc">null</font>) {
<font color="#0066cc">return</font> <font color="#0066cc">false</font>;
}
<font color="#0066cc">let</font> proto = Object.getPrototypeOf(left);
<font color="#0066cc">while</font> (proto !== <font color="#0066cc">null</font>) {
<font color="#0066cc">if</font> (proto === right.prototype) {
<font color="#0066cc">return</font> <font color="#0066cc">true</font>;
}
proto = Object.getPrototypeOf(proto);
}
<font color="#0066cc">return</font> <font color="#0066cc">false</font>;
}
说明:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 用
Object.getPrototypeOf()替代__proto__更标准、更安全(__proto__是非标准但广泛支持的访问器) - 先判断
left是否为有效对象,排除null和原始值(如myInstanceof(42, Number) === false,而原生42 instanceof Number也是false) - 循环中不包含
left自身,只查其原型及更高层,与原生行为一致
注意几个易错点
-
right必须是函数,否则访问right.prototype可能出错或语义不符;实际中可加typeof right === 'function'校验,但原生instanceof对非函数右操作数会直接抛TypeError,手写可根据需求选择抛错或静默返回false - 不要用
in或hasOwnProperty判断,那是查属性,不是查原型链引用相等 - 不能用
==或===直接比较left和right.prototype,必须走原型链 - 箭头函数没有
prototype,所以obj instanceof () => {}会报错;手写实现中若传入箭头函数,right.prototype为undefined,循环不会命中,最终返回false(与原生一致)
简单验证示例
可以这样测试:
function Foo() {}
const f = new Foo();
console.log(myInstanceof(f, Foo)); // true
console.log(myInstanceof(f, Object)); // true(因为 Foo.prototype.__proto__ === Object.prototype)
console.log(myInstanceof([], Array)); // true
console.log(myInstanceof([], Object)); // true
console.log(myInstanceof('a', String)); // false(原始字符串)
console.log(myInstanceof(new String('a'), String)); // true
结果与原生 instanceof 完全一致。

















