對於網上的關於原型,原型鏈和原型鏈繼承的晦澀語言說明就不累贅了,複製粘貼過來再解釋一遍怕本身也整蒙了,本人最怕空氣忽然安靜,四目對視,大眼對小眼,一臉懵逼。函數
咱們先看下面👇的這張圖:prototype
首先先記住一句話,無論是什麼語言,核心思想都是:萬物皆對象。對象
直接看上圖,有一個函數 function FOO( ){};在 js 中函數都有一個 prototype 方法,這就是函數的原型。(constructor 方法是指向它的函數,本文不作詳細解釋。)blog
圖中 f1 = new FOO ( );在 js 中每一個對象都會有一個 __proto__ 屬性,祖師爺規定的,因此 f1 中也會有 __proto__ 屬性,它指向 FOO 函數的 prototype,咱們說萬物皆對象,因此 FOO 函數的 prototype 方法也是一個對象,那麼它也有一個 __proto__ 屬性,那麼它的 __proto__ 屬性指向它上一級的 prototype,(如上圖),萬物接對象,因此最頂層的就是一個 Object 對象,它也有 __proto__ 屬性,可是它的 __proto__ 上層沒有東西了,因此指向 null。這樣造成的鏈式就是原型鏈了。繼承
在對上圖作完解釋後感受仍是會有點不理解,下面咱們將上述文言文轉化爲白話文。原型鏈
如今有一個函數 function 爹( ){ }; 爹裏面必定有一個方法叫 prototype,即原型。原型
爹.prototype.money = 10000; 在爹的 prototype 里加一個 money 屬性,值爲 10000;io
如今 兒子 = new 爹 ( ); 兒子如今是個對象,那它就有個 __proto__ 屬性,它是從爹 new 出來的實例,那它的 __proto__ 指向爹的 prototype;console
那麼兒子就能夠從爹那裏繼承 money = 10000;即 console.log( 兒子.money ); // 10000function
咱們說萬物皆對象,那爹的 prototype 裏面也應該有個 __proto__ 屬性,它指向爺爺的 prototype ( 原型 );爺爺的 prototype 也有 __proto__ 屬性,指向太爺爺的 prototype ( 原型 ) ...... 萬物皆對象,最後會指向 Object 的 prototype ( 原型 ); 可是祖宗總得有個頭,最後一個祖宗,即 Object ,它的 __proto__ 指向 null ,這就造成了原型鏈。知識遺漏:null 沒有 prototype (原型)。
上面的白話文以下圖所示。
上面咱們將原型,原型鏈和原型鏈繼承簡單介紹完了,如今着重看一下原型鏈繼承。
咱們用構造函數的方法從爹( father ) 那裏 new 了一個兒子( son );當打印 son.money 的時候發現兒子居然也有 10000 塊,這就說明兒子已經從爹那裏繼承了 money = 10000 這個屬性了。那若是這個兒子是個敗家子,他從爹那裏繼承過來 10000 立馬買了個愛糞叉,還剩不到 10000 會是什麼樣子。以下圖所示。
從上圖能夠看出兒子從爹那裏繼承過來的屬性其實就至關於複製了一份,即從爹那裏複製了一張 money = 10000 的銀行卡,本質上並無去花爹卡里的錢,因此小兒子也能夠從爹那裏複製一張銀行卡,卡里 money = 10000。這樣就解釋通了在爹的 prototype ( 原型 )裏的共有屬性任何兒子都能繼承,若是以爲從爹那裏繼承的方法很差的話能夠本身重寫,並不影響其餘兒子去使用從爹那裏繼承的方法。
若是說爹的 prototype 裏面的方法變了兒子要是用的話會怎麼樣呢,看了上面的解釋應該很容易答出來了,由於兒子是繼承爹的,因此爹的變化了,那麼兒子的也會跟這變。以下圖
好了,上述就是本人對 js 原型,原型鏈和原型鏈繼承的我的理解了,再深層次的理解你們能夠看看網上其餘大神的解釋,上述表達若是哪裏有不當之處或者遺漏的地方請大神指出。