arr1 --> Array.prototype --> Object.prototype --> null
虚线 --> 表示__proto__
手写
思路: 遍历原型链
function myInstanceof(obj: any, constructor: Function) {
// 是否是基本数据类型
if (isBase(obj)) {
return false;
}
// 遍历原型链
while (obj) {
if (obj === constructor.prototype) return true;
obj = obj.__proto__;
}
// 原型链上没有
return false;
}
// 是否是基本数据类型
function isBase(obj: any) {
if (obj === null) return true;
if (typeof obj === "object") return false;
if (typeof obj === "function") return false;
return true;
}
// 写法2
// 是否是基本数据类型
function isBase(v: any) {
if (v === null) return true;
if (v === undefined) return true;
if (typeof v === "string") return true;
if (typeof v === "number") return true;
if (typeof v === "boolean") return true;
if (typeof v === "bigint") return true;
if (typeof v === "symbol") return true;
return false;
}
测试
console.log(myInstanceof({}, Object));
console.log(myInstanceof([], Object));
console.log(myInstanceof([], Array));
console.log(myInstanceof({}, Array));
class Foo {}
const f = new Foo();
console.log(myInstanceof(f, Foo));
console.log(myInstanceof(f, Object));
function fn() {}
console.log(myInstanceof(fn, Function));
// 基本数据类型
console.log(myInstanceof(null, Object));
console.log(myInstanceof(undefined, Object));
console.log(myInstanceof("abc", String));
console.log(myInstanceof(100, Number));
new Son()-->Son.prototype=new Father()-->Father.prototype-->Object.prototype--> null
function Father(name, age) {
this.name = name;
this.age = age;
}
Father.prototype.work = function () {
alert("work");
};
function Son(name, age) {
Father.call(this, name, age);
}
Son.prototype = new Father();
Son.prototype.play = function () {
alert("play");
};
const jack = new Son("jack", 19);
const res = instanceof_(jack, Father)
console.log(res) // true
graph TD
son --__proto__--> Son.prototype
Son.prototype --__proto__--> father
father --__proto__--> Father.prototype
Father.prototype--__proto__-->Object.prototype
Object.prototype --__proto__--> null