001原型鏈函數
什麼是原型鏈? 解釋:由__proto__造成的鏈條叫作原型鏈 假設咱們建立了一個Person這個構造函數,而後實例化出一個對象fanchen,當咱們輸出這個實例化對象的時候,這個實例化對象裏面有一個__proto__屬性,這個__proto__屬性指向的是建立本身的那個構造函數的原型,也就是說這個實例化對象的__proto__指向的是Person裏面的prototype這個原型對象,由於prototype是一個對象所以裏面確定也會有一個__proto__。而這個__proto__指向的是建立Person這個構造函數的對象,能夠想象一下誰建立了Person?這個時候咱們就不得不說一句"萬物皆是對象".確定是一個對象建立了Person。而這個對象就是 Function。有對象那麼確定就會有__proto__.那麼咱們能夠想象一下還有什麼能夠建立出來對象嗎?所以對象的頂端也就是null.接下來咱們用案例和內存圖詳細的解釋一波
002方法繼承spa
繼承: 在上一章咱們說了屬性繼承,接下來咱們繼續說下方法繼承。方法的繼承分爲好多種,接下來咱們逐個分析來找出一種最完美的繼承方式 首先咱們仍是回顧一下屬性繼承,咱們先寫一個構造函數Person。而後再建立1個實例化對象fanchen
如今咱們能夠繼承到父級的屬性了,可是貌似父級的方法繼承不了,由於我看到__proto__裏面只有一個work這個方法。那麼咱們如何繼承父級的方法呢?咱們能夠試想同樣fanchen是如何訪問到work這個方法的?由於實例化對象裏面的__proto__指向是建立本身的那個構造函數的原型對象所以能夠訪問。那麼若是如今我用Man的原型對象指向Person的原型對象會發生什麼?
一、原型繼承prototype
Man的原型對象指向Person的原型對象
貌似是能夠的,可是這個原理是什麼呢?同時注意一下上面的constructor的指向。接下來咱們畫一個內存圖來解釋一下原理和弊端。3d
從上面的內存圖中咱們不難看出當Man的原型指向Person的原型的時候首先Man的原型對象斷掉了,隨後咱們又給Man的原型添加了方法work,這個時候你會發現Man的work方法加到了Person身上。這樣確定是不行的,由於咱們怎麼能修改父級的原型對象呢?順便咱們能夠在打印出來父級的原型看一下code
二、原型拷貝對象
上面的方法確定不是特別合理的,那麼咱們能夠想一下既然不能直接將Man的原型指向Person的原型,那麼咱們可不可將Person裏面原型對象的屬性直接拷貝一份,這樣我就不會直接修改到父級的原型了? 廢話少說直接上代碼
貌似特別完美,接下來咱們在查看一下父級有沒有發生改變blog
真的沒有什麼問題啊。那麼接下來咱們經過內存圖來查看下原理及缺點繼承
三、原型鏈繼承內存
從上一章咱們講的原型鏈能夠知道,咱們能夠經過原型鏈訪問父級以及父父級裏面的一些屬性和方法,那麼咱們利用這個特色能夠將Man的原型對象指向Person的一個實例.由於實例裏面確定是有一個__proto__,這樣的話咱們就造成了一個原型鏈。接下來咱們用案例和內存圖來表示
當打印出來的時候確實能夠看到父級的方法也能夠進行訪問,可是有缺點,你們不難發現Man的__proto__裏面多了幾個age name sex 並且值仍是undefined?原型鏈
四、混合繼承
從上面的原型鏈繼承能夠看出,當打印出來fanchen的時候咱們丟失了一個constructor屬性並且還有好多雜亂的屬性,那麼咱們應該如何解決呢?咱們一步一步來
這時候你就會發現終於實現了完美繼承。
五、寄生繼承
在網上會常常見到一種方法叫作寄生繼承。其實看到名字你也能想的到,必定須要一個相似寄生器同樣的東西。其實就是一箇中間函數