圖解原型和原型鏈

HuangJiHua發表於2019-05-01

原型

每一個 js 物件都有一個proto屬性,這個屬性指向了原型,這個屬性在現在來說已經不建議直接使用了,這是瀏覽器在早期為了讓我們訪問到內部屬性[[prototype]]來實現的一個東西.

講到這裡好像還是沒明白什麼是原型,接下來我們根據圖來看看proto都有些啥:

原型圖解
看了上圖你應該明白了吧,原型也是一個物件,並且這個物件中包含了很多函式,所有我們可以得出一個結論:對於obj來說,可以通過__proto__找到了一個原型物件,且原型物件中定義了很多函式讓我們來使用. 另外,從圖片上我還發現了一個constructor屬性,也就是建構函式.

結論:obj.__proto__.constructor === Object.

原型的 constructor 屬性指向了建構函式

obj.__proto__.contructor
接下來,我們展開obj.__proto__.constructor屬性,發現其中還有一個prototype屬性,並且這個屬性對應的值和先前在obj.__proto__中看到的一樣.

得出結論:

  • 物件的__proto__屬性指向了原型;
  • 原型constructor屬性又指向了建構函式;
  • 建構函式又通過它的prototype屬性指回了原型;

::: warning 並不是所有函式都具有constructor屬性,如:Function.prototype.bind() :::

Function.prototype.bind
其實,原型就這麼簡單.

原型鏈

接下來我們根據下面這張圖來看看原型原型鏈等關係,徹底搞明白它.

原型鏈

看完這張圖,接下來我們就來解釋下什麼是原型鏈吧. 其實,原型鏈就是多個物件通過__proto__屬性的方式連結了起來. 為什麼obj物件可以訪問到valueOf函式,因為obj通過原型鏈找到了valueOf函式.

看圖梳理下:

  • __proto__ :是物件就會有這個屬性(強調是物件);函式也是物件,那麼函式也有這個屬性咯,它指向建構函式的原型物件;

  • prototype :是函式都會有這個屬性(強調是函式),普通物件是沒有這個屬性的(JS 裡面,一切皆為物件,所以這裡的普通物件不包括函式物件).它是建構函式的原型物件;

  • constructor :這是原型物件上的一個指向建構函式的屬性。

總結:

  • 每一個物件都有__proto__屬性,__proto__==>Object.prototype(Object 建構函式的原型物件);
  • 每個函式都__proto__prototype屬性;
  • 每個原型物件都有constructor__proto__屬性,其中constructor指回'建構函式', 而__proto__指向Object.prototype;
  • object是有物件的祖先,所有物件都可以通過__proto__屬性找到它;
  • Function是所有函式的祖先,所有函式都可以通過__proto__屬性找到它;
  • 每個函式都有一個prototype,由於prototype是一個物件,指向了建構函式的原型物件
  • 物件的__proto__屬性指向原型,__proto__將物件和原型連結起來組成了原型鏈

參考文獻

相關文章