在 JavaScript 中,instanceof 是一个非常常用的运算符,用于检测某个对象是否是某个构造函数的实例。其本质是判断构造函数的 prototype 是否存在于该对象的原型链中。
本文将系统讲解:
instanceof的基本用法;- 它的底层实现原理;
- 如何手动实现一个
myInstanceof函数; - 常见使用场景和注意事项;
- 相关拓展知识。
一、instanceof 的作用
✅ 基本语法:
object instanceof Constructor
📌 示例代码:
function Person() {}
const p = new Person();
console.log(p instanceof Person); // true
console.log(p instanceof Object); // true
📌 表现说明:
p是Person构造函数创建的实例;p.__proto__ === Person.prototype;- 因此
instanceof返回true;
二、instanceof 的实现原理
🔍 核心逻辑:
- 获取对象的原型(
__proto__); - 获取构造函数的
prototype属性; - 沿着对象的原型链向上查找;
- 如果找到某个原型等于构造函数的
prototype,返回true; - 如果查到原型链顶端(即
null),仍未找到则返回false。
三、手动实现一个 myInstanceof 函数
我们可以基于上述原理,手动实现一个类似 instanceof 的功能:
✅ 实现代码如下:
function myInstanceof(left, right) {
// 获取对象的原型
let proto = Object.getPrototypeOf(left);
// 获取构造函数的 prototype 属性
const prototype = right.prototype;
// 沿着原型链查找
while (proto !== null) {
if (proto === prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
🧪 测试示例:
function Person() {}
function Animal() {}
const p = new Person();
console.log(myInstanceof(p, Person)); // true
console.log(myInstanceof(p, Animal)); // false
console.log(myInstanceof(p, Object)); // true
console.log(myInstanceof(null, Object)); // false
四、关键 API 解释
| 方法 | 描述 |
|---|---|
Object.getPrototypeOf(obj) | 获取对象的原型,等价于 obj.__proto__,但更标准、安全 |
constructor.prototype | 构造函数的原型对象,实例的 __proto__ 会指向它 |
while (proto !== null) | 遍历原型链直到顶层(Object.prototype -> null) |
五、注意事项与常见误区
❗ 1. instanceof 对原始类型无效
console.log(123 instanceof Number); // false
console.log(new Number(123) instanceof Number); // true
📌 原始值没有原型链,所以 instanceof 不适用于原始类型。
❗ 2. 跨框架/窗口环境失效
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const xArray = iframe.contentWindow.Array;
const arr = new xArray();
console.log(arr instanceof Array); // false
console.log(myInstanceof(arr, Array)); // false
📌 原因:不同执行上下文中的构造函数是不同的,原型链不一致。
❗ 3. 不能判断 null 和 undefined
console.log(myInstanceof(null, Object)); // false
console.log(myInstanceof(undefined, Object));// false
📌 这些不是对象,没有原型链,因此不会通过 instanceof 判断。
六、一句话总结
instanceof的核心原理是沿着对象的原型链查找是否存在构造函数的prototype。我们可以通过Object.getPrototypeOf()手动模拟其实现,但在跨框架或处理原始类型时需特别注意。
💡 进阶建议
- 学习
Symbol.hasInstance,可以自定义instanceof的行为; - 使用 TypeScript 可以提升类型安全性,避免运行时错误;
- 在 Vue / React 中结合 PropTypes 或 TypeScript 类型守卫进行类型判断;
- 理解原型链机制有助于深入理解 JavaScript 继承体系;