轉載自:https://www.cnblogs.com/az96/p/6014621.htmljavascript
一直認爲原型鏈太過複雜,尤爲看過某圖後被繞暈了一整子,今天清理硬盤空間(渣電腦),偶然又看到這圖,勾起了點回憶,因而索性複習一下原型鏈相關的內容,表達能力欠缺邏輯混亂別見怪(爲了防止新人__(此處指我)__被在此繞暈,圖片就放在末尾了。)html
如下三點須要謹記java
1.每一個對象都具備一個名爲__proto__的屬性;函數
2.每一個構造函數(構造函數標準爲大寫開頭,如Function(),Object()等等JS中自帶的構造函數,以及本身建立的)都具備一個名爲prototype的方法(注意:既然是方法,那麼就是一個對象(JS中函數一樣是對象),因此prototype一樣帶有__proto__屬性);prototype
3.每一個對象的__proto__屬性指向自身構造函數的prototype;code
直接上代碼.....htm
function Fun(){ } // 我創造了一個函數Fn // 這個函數由Function生成(Function做爲構造函數) var fn=new Fun() // 我建立了一個函數fn // 這個函數由Fn生成(Fn做爲構造函數) console.log(fn.__proto__===Fun.prototype) //true // fn的__proto__指向其構造函數Fun的prototype console.log(Fun.__proto__===Function.prototype) //true // Fun的__proto__指向其構造函數Function的prototype console.log(Function.__proto__===Function.prototype) //true // Function的__proto__指向其構造函數Function的prototype // 構造函數自身是一個函數,他是被自身構造的 console.log(Function.prototype.__proto__===Object.prototype) //true // Function.prototype的__proto__指向其構造函數Object的prototype // Function.prototype是一個對象,一樣是一個方法,方法是函數,因此它必須有本身的構造函數也就是Object console.log(Fun.prototype.__proto__===Object.prototype) //true // 與上條相同 // 此處能夠知道一點,全部構造函數的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身) console.log(Object.__proto__===Function.prototype) //true // Object做爲一個構造函數(是一個函數對象!!函數對象!!),因此他的__proto__指向Function.prototype console.log(Object.prototype.__proto__===null) //true // Object.prototype做爲一切的源頭,他的__proto__是null // 下面是一個新的,額外的例子 var obj={} // 建立了一個obj console.log(obj.__proto__===Object.prototype) //true // obj做爲一個直接以字面量建立的對象,因此obj__proto__直接指向了Object.prototype,而不須要通過Function了!! // 下面是根據原型鏈延伸的內容 // 還有一個上文並未提到的constructor, constructor在原型鏈中,是做爲對象prototypr的一個屬性存在的,它指向構造函數(因爲主要講原型鏈,這個就沒在乎、); console.log(obj.__proto__.__proto__===null) //true console.log(obj.__proto__.constructor===Object) //true console.log(obj.__proto__.constructor.__proto__===Function.prototype) //true console.log(obj.__proto__.constructor.__proto__.__proto__===Object.prototype) //true console.log(obj.__proto__.constructor.__proto__.__proto__.__proto__===null) //true console.log(obj.__proto__.constructor.__proto__.__proto__.constructor.__proto__===Function.prototype) //true // 以上,有興趣的能夠一一驗證 F12搞起.
prototype是構造函數獨有的屬性;對象
對象的__prototype__屬性一般與其構造函數的prototype屬性相互對應;blog
全部構造函數的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身);繼承
須要注意的指向是
Function的__proto__指向其構造函數Function的prototype;
Object做爲一個構造函數(是一個函數對象!!函數對象!!),因此他的__proto__指向Function.prototype;
Function.prototype的__proto__指向其構造函數Object的prototype;
Object.prototype的__prototype__指向null(盡頭);
原型鏈經常使用於繼承相關的操做.
在文章結構順便附送上倆個與原型鏈相關的方法....歡迎食用
1.
若是 object2 不是一個對象或者 object1 沒有出如今 object2 中的原型鏈中,isPrototypeOf 方法將返回 false。
附圖:
理解了上面兩條鏈之後,這兩個全圖實際上就不難理解了。分享一下,怎麼來讀懂這個圖:
constructor
都會指向它們的構造函數;而構造函數也是對象,它們最終會一級一級上溯到 Function
這個構造函數。Function
的構造函數是它本身,也即此鏈的終結;Function
的 prototype
是 Function.prototype
,它是個普通的原型對象;__proto__
都會指向其構造函數的原型對象 [Class].prototype
;而全部原型對象,包括構造函數鏈的終點 Function.prototype
,都會最終上溯到 Object.prototype
,終結於 null。也便是說,構造函數鏈的終點 Function
,其原型又融入到了原型鏈中:Function.prototype -> Object.prototype -> null
,最終抵達原型鏈的終點 null
。至此這兩條契合到了一塊兒。