理解什麼是原型鏈,prototype和__proto__的區別

原文鏈接:https://blog.csdn.net/lc237423551/article/details/80010100

1.Javascript中所有的對象都是Object的實例,並繼承Object.prototype的屬性和方法,也就是說,Object.prototype是所有對象的爸爸。(個人感覺搞清楚這一點很重要) 。

   在對象創建時,就會有一些預定義的屬性,其中定義函數的時候,這個預定義屬性就是prototype,這個prototype是一個普通的對象。

而定義普通的對象的時候,就會生成一個__proto__,這個__proto__指向的是這個對象的構造函數的prototype.

詳情請看例一:(建議大家用谷歌瀏覽器查看這些對象的屬性);

  1. function A(a){
  2. this.a = a;
  3. }

首先定義一個函數a,如上面所說,函數在被定義的時候就擁有了一個prototype對象。我們來打印看一下

console.log(A.prototype)

瀏覽器的結果:


如上圖,這就是函數a的prototype對象,(記住我們最開始說的,凡是對象都會有一個屬性那就是__proto__)。這個__proto__指向的就是他的構造函數的prototype 而這個函數a的prototype對象的構造函數是誰呢? 沒錯就是開頭說到的Object.prototype。

看如下代碼:

  1.        console.log(A.prototype.__proto__)
  2. console.log(Object.prototype)

而這兩個的結果如下:


打印出來是同一個東西,也就是說Object.prototype是所有函數的爹,當你聲明一個函數的時候也就是相當於對Object的實例化。這裏可以對比一下new一個實例。

我們也可以用幾個方法來驗證一下:

  1.         console.log(Object.prototype.isPrototypeOf(A))//true
  2. console.log(A instanceOf Object) //true

函數a的prototype對象的另一個屬性是constructor這個屬性就指向了函數a本身,也就是指向了他自己的構造函數。


2.我們在來用一個實例對象來說明一下原型,代碼如下:

    

  1.         function B(b){
  2. this.b = b;
  3. }
  4. var b = new B('lc');

當我們聲明一個函數B時就自動創建了prototype對象。而b是構造函數的B的實例,這是候b是一個對象,而我們知道,對象只有__proto__屬性。而這個屬性是指向他的構造函數(B)的prototype屬性。這時候我們來打印一下b

console.log(b)

可以看到b中只有__proto__屬性,而這個屬性是指向他的構造函數的prototype對象的,也就是說

(b.__proto__==B.prototype)答案爲true;

這就是js中的prototype和__proto__的區別。


那麼什麼是原型鏈呢?接着上面的講,我們都知道對象都有一個toString方法。上述的實例化對象b也可以toString,

而實例化對象b本身並沒有toString的方法,那他就會沿着它的__proto__向他的構造函數B的prototype對象去找,而這裏也沒有,那他就會 繼續沿着B.prototype.__proto__向上找。而B.prototype.__proto__指向的就是Object.prototype。

我們打印一下Object.prototype:


這就是原型鏈查找,而則一層一層的鏈接 關係就是原型鏈。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章