之前写js数据类型的时候有提到instanceof,今天就来深层次解剖一下它
主要作用
instanceof 主要作用就是判断一个实例是否属于某种类型 说直白点就是 左边的对象是否是它右边的类的实例
原理
instanceof 的原理就是根据 原型链 挨个往上查找看是否有与目标对象的prototype相等的原型,直到最顶层Object还找不到,那么就返回false,否则结果就是true。
你可以理解为在一个玄幻世界,你有一个宗门,然后你在外历练惹了事,后面人让你给交代。这个时候肯定是比拼拳头大小(A instanceof B)。先是你自己去,你打不过了,你师父他们不能看着你一直被按在地上摩擦吧?所以你师父就上,你师父也打不过就你师爷爷上,你师爷爷还打不过就你们老祖上,如果打过了,就自然无事)(返回 true),要是打不过,那就只能给出补偿(返回 false)
现在知道为什么这俩都是 true 了吧?? 因为你的们不是单脉相传,你也有师兄师弟啊,他惹了事,一样回家找家长,哈哈哈
说了原理,我们再来手写实现
手写
function constRenInstanceof(target, origin) {
// 限制左侧参数为对象
if (![' function', 'object'].includes(typeof target) || target == null) return false;
// 获取隐式原型 __proto__
let tp = target.__proto__
// 沿着原型链循环向上去找
while (tp !== null) {
// 如果找到就返回true (实例对象的隐式原型 等于 其构造函数的 显示原型)
if (tp === origin.prototype) return true
// 逐级向上找
tp = tp.__proto__
}
// 原型链的尽头是null,如果到null都还找不到,就返回false
return false
};
function Fun() { };
var f = new Fun();
function child() { };
function father() { };
child.prototype = new father();
var son = new child();
console.log('constRenInstanceof([], Object)', constRenInstanceof([], Object));
console.log('constRenInstanceof({}, Object)', constRenInstanceof({}, Object));
console.log('constRenInstanceof(f, Fun)', constRenInstanceof(f, Fun));
console.log('constRenInstanceof(son, child)', constRenInstanceof(son, child));
console.log('constRenInstanceof(son, father)', constRenInstanceof(son, father));
console.log('constRenInstanceof(f, Object)',constRenInstanceof(f, Object));
console.log('constRenInstanceof(son, Object)',constRenInstanceof(son, Object));
是不是发现其实很多问题并没有想象中那么难?