JavaScript中isPrototypeOf函数详解

有时看一些框架源码的时候,会碰到 isPrototypeOf() 这个函数,那么这个函数有什么作用呢?

isPrototypeOf()

isPrototypeOf() 是 Object函数(类)的下的一个方法,用于判断当前对象是否为另外一个对象的原型,如果是就返回 true,否则就返回 false。

这个函数理解的关键是在原型链上,这个据说是JavaScript的三座大山之一。

这里不详述其中的原理,简单的来讲就是3点:

1. 函数对象,都会天生自带一个prototype原型属性。
2. 每一个对象也天生自带一个属性__proto__指向生成它的函数对象的prototype。
3. 函数对象的prototype也有__proto__指向生成它的函数对象的prototype。 

示例1,Object类实例:

let o = new Object();
console.log(Object.prototype.isPrototypeOf(o)); // true 

因为o对象是Object的实例,所以o对象的原型(__proto__)指向Object的原型(prototype),上面会输出true。

示例2,自己定义Human类:

function Human() {}
let human = new Human();

console.log(Human.prototype.isPrototypeOf(human)); // true 

这例和上例类似,因为human对象是Human的实例,所以human对象的原型(__proto__)指向Human的原型(prototype),上面会输出true。

示例3,再来看看Object的原型(prototype)是否是human的原型:

console.log(Object.prototype.isPrototypeOf(human)); // true 

为什么呢?,用代码可能更好解释,请看下面推导:

// 因为 Human 的原型(prototype)中的原型(__proto__)指向 Object 的原型(prototype)
Human.prototype.__proto__ === Object.prototype
// 又因为 human 的原型(__proto__)指向 Human 的原型(prototype)
huamn.__proto__=== Human.prototype
// 所以human对象的原型(__proto__)的原型(__proto__)指向Object的原型(prototype)
huamn.__proto__.__proto__=== Object.prototype 

如果查看human的结构就很容易清楚了:

那 Object 的原型(prototype) 是不是就是 human 对象的原型呢?确切的说Object 的原型(prototype)是在 human 的原型链上。

示例4,Object.prototype是否是内置类的原型:

JavaScript中内置类Number、String、Boolean、Function、Array因为都是继承Object,所以下面的输出也都是true:

console.log(Object.prototype.isPrototypeOf(Number)); // true
console.log(Object.prototype.isPrototypeOf(String)); // true
console.log(Object.prototype.isPrototypeOf(Boolean)); // true
console.log(Object.prototype.isPrototypeOf(Array)); // true
console.log(Object.prototype.isPrototypeOf(Function)); // true 

自然Object.prototype也是Number、String、Boolean、Function、Array的实例的原型。

示例5,Object也是函数(类):

另外值得一提的是 Function.prototype 也是Object的原型,因为Object也是一个函数(类),它们是互相生成的。

请看下面输出:

console.log(Object.prototype.isPrototypeOf(Function)); // true
console.log(Function.prototype.isPrototypeOf(Object)); // true 

和 instanceof 的区别

instanceof 是用来判断对象是否属于某个对象的实例。

例如:

function Human() {}
let human = new Human();

// human 是 Human 的实例,所以结果输出true
console.log(human instanceof Human); // true

// 因为所有的类都继承Object,所以结果也输出true
console.log(human instanceof Object); // true

// 因为 human 对象不是数组,所以结果输出false
console.log(human instanceof Array); // false 

再来一些内置类的例子:

// 【1,2,3] 是 Array 的实例,所以输出true
console.log([1, 2, 3] instanceof Array); // true

// 方法 function(){} 是 Function的实例,所以输出true
console.log(function(){} instanceof Function); 

instanceof 作用的原理就是判断实例的原型链中能否找到类的原型对象(prototype),而 isPrototypeOf 又是判断类的原型对象(prototype)是否在实例的原型链上。

所以我的理解,这两个表达的意思是一致的,就是写法不同,下面两个输出应该是一致的:

console.log(A instanceof B);
console.log(B.prototype.isPrototypeOf(A)); 

小结

其实要理解 isPrototypeOf 函数,关键是要理解原型链这个玩意。

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值