天天看點

原型和原型鍊的了解_從instanceof身上深入了解原型/原型鍊

原型和原型鍊的了解_從instanceof身上深入了解原型/原型鍊

今天将延續這篇文章,借助一個老朋友——instanceof運算符,将通過它以及結合多次講的原型/原型鍊經典圖來深入了解原型/原型鍊。

對于原始類型(primitive type)的值,即string/number/boolean,你可以通過typeof判斷其類型,但是typeof在判斷到合成類型(complex type)的值的時候,傳回值隻有object/function,你不知道它到底是一個object對象,還是數組,也不能判斷出Object 下具體是什麼細分的類型,比如 Array、Date、RegExp、Error 等。

官方對

instanceof

運算符的解釋是傳回一個布爾值,表示對象是否為某個構造函數的執行個體。比如:

function Foo() {}
var f1 = new Foo();

console.log(f1 instanceof Foo);  // true
console.log(f1 instanceof Object);  // true
           

上面代碼中,對象f1是構造函數Foo的執行個體,是以傳回true,但是“f1 instanceof Object”為什麼也是true呢?

至于為什麼等會再解釋,先把instanceof判斷的規則告訴大家。根據以上代碼看下圖:

原型和原型鍊的了解_從instanceof身上深入了解原型/原型鍊

instanceof

運算符的左邊是執行個體對象,右邊是構造函數,左邊變量暫稱為A,右邊變量暫稱為B。它會檢查右邊構造函數的原型對象(prototype),是否在左邊對象的原型鍊上。

通俗一點來講,instanceof的判斷規則是:

instanceof會檢查整個原型鍊,将沿着A的__proto__這條線來一直找,同時沿着B的prototype這條線來一直找,直到能找到同一個引用,即同一個對象,那麼就傳回true。如果找到終點還未重合,則傳回false

。即上圖中的 f1-->__proto__ 和 Foo-->prototype 指向同一個對象,console.log(f1 instanceof Foo)為true。

按照以上規則,重新來看看“ f1 instanceof Object ”這句代碼為什麼是true? 根據上圖很容易就能看出來, f1-->__proto__-->__proto__ 和Object-->prototype 指向同一個對象,console.log(f1 instanceof Object)為true。

通過上面的規則,可以很好地解釋一些比較怪異的現象,例如:

console.log(Object instanceof Function);   // true
console.log(Function instanceof Object);   // true
console.log(Function instanceof Function);   // true
console.log(Object instanceof Object);   // true
           

這些就是這篇文章所講的看似很混亂的東西,現在知道為何了吧。

但還有一種特殊情況,就是左邊對象的原型鍊上,隻有

null

對象。這時,

instanceof

判斷會失真。

var obj = Object.create(null);
typeof obj // "object"
Object.create(null) instanceof Object // false
           

上面代碼中,

Object.create(null)

傳回一個新對象

obj

,它的原型是

null

Object.create

後續會有專門文章介紹)。右邊的構造函數

Object

prototype

屬性,不在左邊的原型鍊上,是以

instanceof

就認為

obj

不是

Object

的執行個體。但是,隻要一個對象的原型不是

null

instanceof

運算符的判斷就不會失真。

說到這裡,繼續貼上這幅原型/原型鍊的經典圖,是否現在看起來沒那麼複雜了呢。

原型和原型鍊的了解_從instanceof身上深入了解原型/原型鍊

如果這篇文章你看的比較仔細,再結合剛才介紹的instanceof的概念規則,相信能看懂上面這張圖的内容了。

那麼問題又出來了。instanceof這樣設計,到底有什麼用?到底instanceof想表達什麼呢?

這就要重點講講繼承了,即instanceof表示的就是一種繼承關系,或者原型鍊的結構,請看後續文章介紹。

如果覺得文章對你有些許幫助,歡迎在我的GitHub部落格點贊和關注,感激不盡!