🎯 一、面试必问:你能手写 instanceof 吗?
面试官为什么问这个问题:
- 想知道你是否理解 JS 的原型链查找机制
- 能否用递归 + 原型指针逻辑模拟语言行为
🔍 二、instanceof 的原理回顾
a instanceof B 本质判断的是:
B.prototype 是否在 a.__proto__ 的原型链上
即:
a.__proto__ === B.prototype
a.__proto__.__proto__ === B.prototype
a.__proto__.__proto__.__proto__ === B.prototype
...
直到 __proto__ === null 为止
✍️ 三、手写 instanceof
function myInstanceof(obj, constructor) {
if (typeof obj !== 'object' || obj === null) return false;
let proto = Object.getPrototypeOf(obj); // 相当于 obj.__proto__
const prototype = constructor.prototype;
while (proto) {
if (proto === prototype) return true;
proto = Object.getPrototypeOf(proto); // 向上查找
}
return false;
}
✅ 四、测试验证
function Person() {}
const p = new Person();
console.log(myInstanceof(p, Person)); // true
console.log(myInstanceof(p, Object)); // true
console.log(myInstanceof(p, Array)); // false
console.log(myInstanceof(null, Person)); // false
🧠 五、考点总结与易错点
| 易错点 | 正解 | ||
|---|---|---|---|
忘了处理 null | `typeof obj !== 'object' | obj === null` | |
直接 __proto__ | 推荐用 Object.getPrototypeOf() 更规范 | ||
| 判断条件错误 | proto === constructor.prototype,不要搞混 |
📘 六、进阶加分项
6.1 Symbol.hasInstance
实际上 a instanceof B 会调用:
B[Symbol.hasInstance](a)
你甚至可以这样 hack:
class A {
static [Symbol.hasInstance](obj) {
return false;
}
}
console.log(new A() instanceof A); // false !!!
这是 instanceof 可被重写的入口,了解这个能在面试中加分。
🧩 七、图示理解
┌────────────┐
│ constructor│
└─────┬──────┘
↓
┌──────────────────┐
│ constructor.prototype │
└────────┬─────────┘
↓
Object.getPrototypeOf(obj)
↓
一直往上找,直到 === constructor.prototype 为止