本文主要是完全講明白prototype和__proto__ 是幹嗎的,相信不少同窗也跟我同樣,傻傻的分不清楚二者應該如何使用?、在原型鏈中到底起到什麼做用?、 在繼承中起到什麼做用?、javascript爲何會設計出這兩個屬性?等一系列問題,網上查遍許多資料,看的也是雲裏霧裏一頭霧水,接下來,本文就通俗易懂的來說解以上問題,也當作本身的學習筆記。javascript
若是你以前瞭解過 java 這種面向對象編程的語言,你應該會熟悉類的概念,在面向對象編程的語言中,首先設計出類(class),而後再生成類的實例(實例化成對象)。 可是 在 javascript 語言中,並無類的概念,全部的數據類型都是對象(object) ,這並無任何問題,不是全部的編程語言都必須向 java 同樣依賴類的概念,C 語言就沒有類的概念,同樣活的很好。可是咱們不得不認可,類是思想會給項目工程問題帶來不少方便。若是想構建一個大型項目,那必然會涉及到繼承,繼承問題,就須要經過類來實現,可是在 javascript 中並無類的概念,那應該怎麼辦呢,咱們能夠模仿類,因此prototype和__proto__ 就衍生出來了。html
也能夠參考阮一峯老師的:Javascript繼承機制的設計思想java
在講解prototype和__proto__以前,咱們首先來說解一下 javascript 中的數據類型。爲何要先講下數據類型呢,由於prototype和__proto__用到了Function 和 Object 兩種數據類型。 javascript 數據類型分爲兩種:編程
咱們能夠用 typeof 來判斷一個變量的數據類型,5種基本數據類型均可以用 typeof 判斷出來(Null爲 object), 而引用數據類型只能判斷出 object 和 function 兩種類型,也就是說,引用類型其實分兩種 Object 和 Function ,其餘的類型都是 Object 類型衍生出來的。編程語言
代碼以下: ide
經過上面的講解,接下來咱們的重點要放在 Function 和 Object 兩個類型上。函數
從上圖咱們能夠看出,構造函數自己是一個 function ,而構造函數返回的實例實際上是一個object學習
明確了 Function 與 Object 的關係後,咱們接下來說解在繼承中prototype和__proto__起到了什麼做用。ui
在相似 java 這種語言中,繼承的概念是經過類和類之間實現的,但 javascript 根本沒有類,都是對象,因此,在 javascript中,繼承的概念是經過對象和對象之間實現的。this
在考慮 javascript 繼承的時候,範圍只限於引用數據類型,雖然引用數據類型分爲 Function 和 Object 兩種,但在繼承問題上,不須要區分 Function 和 Object,只須要統一當作對象便可。
那麼,javascript 到底是經過什麼來肯定繼承關係的呢? 答案是 proro
__proto__和prototype 不一樣,prototype 只在 Function 中有,而__proto__則在Function和Object中都有。
代碼以下:
簡單總結javascript繼承的本質: 一個對象 A的__proto__屬性指向的那個對象B,B就是 A 的原型對象(或者叫父對象),對象 A 可使用對象 B 中的屬性和方法,同時也可使用對象 B 的 原型對象C 上的屬性和方法,以此遞歸,就是所謂的原型鏈
示例代碼:
以上代碼實現了 javascript 最簡單的繼承,彷佛沒什麼,一個__proto__就實現了繼承問題。那還要 prototype 作什麼呢?prototype在繼承中又起什麼做用呢,其實 prototype 真正起做用的是把 Function 當作構造函數使用的時候,由於__proto__ 並非官方標準定義的屬性,因此藉助 prototype屬性來模仿類和類之間的繼承模式。
接下來重點分析用 Function類型構造對象過程,當你知道使用 new 操做符都作了什麼的時候,你就很清楚 prototype 的做用了。
經過上面的分析,咱們知道 p 是 object 的類型,Parent 是 Function 類型。 在 java中,若是你這麼寫,那麼 Parent 應該是一個類(class),可是 javascript 中並無類,可是咱們又很想借鑑這種語法形式,應該怎麼辦呢,這個任務只能交給 Function。 看下完整代碼:
上面這種寫法,就是經典的構建構造函數,可是 new到底都幹了啥呢?
這樣,一個鮮活的實例就被建立出來了。
最後,咱們用Stack Overflow上關於這個問題得票最多答案做爲總結,他解釋的很是簡單
下面是答案:
__proto__is the actual object that is used in the lookup chain to resolve methods, etc. prototype is the object that is used to build __proto__when you create an object with new
翻譯一下:
__proto__是真正用來查找原型鏈去獲取方法的對象。
prototype是在用new建立對象時用來構建__proto__的對象