instanceof的用法
instanceof用于检测一个对象是否是某个构造函数(或类)的实例,其核心是判断对象的原型链上是否存在该构造函数的 prototype 属性。
// 例子1:数组实例
const arr = [1,2,3];
console.log(arr instanceof Array); // true → Array.prototype 在 arr 原型链上
console.log(arr instanceof Object); // true → Object.prototype 是原型链终点
// 例子2:类实例
class Person {}
const p = new Person();
console.log(p instanceof Person); // true → Person.prototype 在 p 原型链上
// 例子3:基本类型不生效
const str = "hello";
console.log(str instanceof String); // false → 基本类型没有原型链
手写instanceof
首先来分析一下instanceof的工作原理,left(对象) 的原型链上,是否存在 right(构造函数) 的 prototype 属性
function myInstanceof(left, right) {
// 步骤1:获取 left 的原型(对象的原型)
let proto = Object.getPrototypeOf(left);
// 步骤2:获取 right 的 prototype(构造函数的原型)
const prototype = right.prototype;
// 步骤3:循环遍历原型链
while (true) {
// 原型链遍历到终点(Object.prototype 的原型是 null),没找到 → false
if (proto === null) return false;
// 找到匹配的 prototype → true
if (proto === prototype) return true;
// 向上遍历:获取上一层原型
proto = Object.getPrototypeOf(proto);
}
}
// 测试数组
const arr = [1,2,3];
console.log(myInstanceof(arr, Array)); // true(符合预期)
console.log(myInstanceof(arr, Object)); // true(符合预期)
// 测试类实例
class Person {}
const p = new Person();
console.log(myInstanceof(p, Person)); // true(符合预期)
console.log(myInstanceof(p, Object)); // true(符合预期)
// 测试基本类型
const str = "hello";
console.log(myInstanceof(str, String)); // false(符合预期)
优化
结果正确说明,但是还可以完善一下
问题 1:如果 left 不是对象(比如基本类型),Object.getPrototypeOf 会报错吗?
- 验证:
Object.getPrototypeOf(1)→ 报错(Uncaught TypeError) - 解决:先判断
left是否是对象(排除null/undefined,因为typeof null === 'object',需要单独判断)
问题 2:如果 right 没有 prototype(比如 right 是 null/undefined 或基本类型),会报错吗?
- 验证:
myInstanceof(arr, 1)→ 报错(right.prototype 不存在) - 解决:先判断
right是否是函数(因为只有构造函数 / 类才有prototype属性)
function myInstanceof(left, right) {
// 边界处理1:left 是 null/undefined → 直接返回 false
if (left === null || typeof left !== 'object') return false;
// 边界处理2:right 不是函数 → 直接返回 false(构造函数必须是函数)
if (typeof right !== 'function') return false;
// 步骤1:获取 left 的原型(对象的原型)
let proto = Object.getPrototypeOf(left);
// 步骤2:获取 right 的 prototype(构造函数的原型)
const prototype = right.prototype;
// 步骤3:循环遍历原型链
while (true) {
// 原型链遍历到终点(Object.prototype 的原型是 null),没找到 → false
if (proto === null) return false;
// 找到匹配的 prototype → true
if (proto === prototype) return true;
// 向上遍历:获取上一层原型
proto = Object.getPrototypeOf(proto);
}
}