JS基礎系列--原型和原型鏈的通俗理解

在開始講原型和原型鏈以前,咱們先確認如下幾個概念:git

  1. 全部函數都含有一個prototype屬性(顯式屬性)
  2. 全部引用類型(函數,數組,對象)都有一個_proto_屬性(隱式屬性)
  3. 原型對象:擁有prototype屬性的對象,在定義函數時就被建立

先知道以上3點,下面咱們一步一步來講明:github

第一步:咱們建立一個構造函數Personsegmentfault

function Person(name){
    this.name = name;  // 屬性name
    this.sayHello = function(){ // 方法sayHello
        console.log(name + 'say hello');
    }
}複製代碼

如今建立一個實例對象moose並傳入名字「moose」數組

var moose = new Person('moose');複製代碼

這時候咱們來打印一下,看看moose是否是擁有Person的屬性和方法瀏覽器

moose.sayHello(); // moose say hello複製代碼

    咱們知道moose這個對象在建立的時候並無直接建立sayHello()方法,即便你們知道從Person中繼承過來的,那究竟是怎麼實現的呢?這就是咱們接下來要講的原型和原型鏈。bash

    在Person這個構造函數定義的時候,同時建立的還有一個與之關聯的「原型對象」,這個對象畢竟不是咱們手動建立命名的一個對象,那要使用這個「原型對象」怎麼辦呢?JS提供了一個屬性「prototype」給函數。Person.prototype就指向這個「原型對象」。函數

    這個時候咱們經過Person這個構造函數建立了一個實例對象「moose」,要想實現繼承這樣一個關係,moose必須可以使用Person中的屬性和方法。JS的作法是給實例對象提供了一個"__proto__"的屬性,moose.__proto__也指向Person對應的這個實例對象。這樣咱們就得出了一個小結論:this

console.log(Person.prototype === moose.__proto__); // true複製代碼

到目前爲止,原型鏈繼承就實現了。spa

第一步原型關係圖以下:prototype


第二步:既然實例對象和構造函數均可以指向原型,那麼原型是否有屬性指向構造函數或者實例呢?

很遺憾,原型沒有指向實例對象的屬性,可是指向構造函數的有啊~:constructor登場

console.log(Person === Person.prototype.constructor); // true複製代碼


既然說了原型相關的概念,咱們不妨在說一下原型鏈,簡單的說,原型鏈就是一條由一堆上下等級分明的原型組成的繼承鏈。

第三步:就上面的例子而言:moose經過__proto__找到本身的原型,繼承原型對應函數的屬性和方法。那麼咱們難想到,原型對象自己就是一個對象呀,也擁有__proto__屬性,那麼它的原型又會是什麼呢?

console.log(Person.prototype);複製代碼


console.log(Person.prototype.__proto__ === Object.prototype); // true複製代碼

從瀏覽器中打印出的結果頁能夠看到,Object.prototype原型的constructor屬性指向的是Object函數。



那麼Object.prototype的原型又是什麼呢?

console.log(Object.prototype.__proto__); // null複製代碼


這就說明Object.prototype 已經沒有原型了,Object對象是根對象。

以上一整個查找原型的過程走的就是這樣一條清晰的原型鏈。

拓展問題:instanceof原理是什麼?

// 咱們以數組爲例
var arr = []
arr instanceof Array複製代碼

    instanceof原理就是利用了原型鏈,當執行arr instanceof Array時,會從arr的_proto_一層一層往上找,看是否能不能找到Array的prototype。
    咱們知道var arr = [] 實際上是var arr = new Array()的語法糖,因此arr的_proto_指向Array的prototype,結果返回true

到此爲止,咱們大致的梳理了一下原型以及原型鏈相關的內容

特別感謝提供相關內容參考:

    github.com/mqyqingfeng…

    www.jianshu.com/p/6ec881835…

    segmentfault.com/a/119000001…

附:感謝您的閱讀,但願對您有所幫助。若是以上內容中存在疑問和錯誤,歡迎留言或者私信。

相關文章
相關標籤/搜索