JavaScript中isPrototypeOf函數

 有時看一些框架源碼的時候,會碰到 isPrototypeOf() 這個函數,那麼這個函數有什麼作用呢?

1、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中內置類NumberStringBooleanFunctionArray因為都是繼承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也是NumberStringBooleanFunctionArray的實例的原型。

示例5,Object也是函數(類):

另外值得一提的是 Function.prototype 也是Object的原型,因為Object也是一個函數(類),它們是互相生成的。

請看下面輸出:

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

2、和 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 函數,關鍵是要理解原型鏈這個玩意。

到此這篇關於JavaScriptisPrototypeOf函數的文章就介紹到這瞭,更多相關JavaScript中isPrototypeOf內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: