instanceof 原理实现
手写 JavaScript 的 instanceof 操作符
问题
手写实现 instanceof 操作符,判断对象是否是某个构造函数的实例。
解答
instanceof 的原理是沿着对象的原型链查找,判断构造函数的 prototype 是否在原型链上。
function myInstanceof(obj, constructor) {
// 基本类型直接返回 false
if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
return false;
}
// 获取构造函数的 prototype
const prototype = constructor.prototype;
// 获取对象的原型
let proto = Object.getPrototypeOf(obj);
// 沿原型链向上查找
while (proto !== null) {
if (proto === prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
测试用例
function Person(name) {
this.name = name;
}
const p = new Person('Tom');
console.log(myInstanceof(p, Person)); // true
console.log(myInstanceof(p, Object)); // true
console.log(myInstanceof(p, Array)); // false
console.log(myInstanceof([], Array)); // true
console.log(myInstanceof([], Object)); // true
// 基本类型
console.log(myInstanceof(1, Number)); // false
console.log(myInstanceof('str', String)); // false
console.log(myInstanceof(null, Object)); // false
使用 __proto__ 的写法
function myInstanceof(obj, constructor) {
if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
return false;
}
let proto = obj.__proto__;
while (proto) {
if (proto === constructor.prototype) {
return true;
}
proto = proto.__proto__;
}
return false;
}
关键点
instanceof检查构造函数的prototype是否在对象的原型链上- 基本类型(非对象)直接返回
false - 使用
Object.getPrototypeOf()比__proto__更规范 - 原型链的终点是
null,作为循环终止条件 - 所有对象都是
Object的实例(除了Object.create(null)创建的对象)
目录