🍭 圖解原型和原型鏈

20190314150227.png

圖解原型和原型鏈

原型和原型鏈是 JS 中不可避免須要碰到的知識點📕,本文使用圖片思惟導圖的形式縷一縷原型、原型鏈、實例、構造函數等等概念之間的關係🌚markdown

Constructor 構造函數

首先咱們先寫一個構造函數 Person,構造函數通常爲了區別普通函數要求首字母大寫:函數

function Person(){}
複製代碼

prototype 原型

原型指的就是一個對象,實例「繼承」那個對象的屬性。在原型上定義的屬性,經過「繼承」,實例也擁有了這個屬性。「繼承」這個行爲是在 new 操做符內部實現的。spa

先不說實例,原型與構造函數的關係就是,構造函數內部有一個名爲 prototype 的屬性,經過這個屬性就能訪問到原型:prototype

20190314132908.png

Person 就是構造函數,Person.prototype 就是原型code

20190314132934.png

instance 實例

有個構造函數,咱們就能夠在原型上建立能夠「繼承」的屬性,並經過 new 操做符建立實例orm

20190314141908.png

比方說 Person,咱們要建立一個 person 實例,那麼使用 new 操做符就能夠實現,並經過 instanceof 來檢查他們之間的關係:對象

20190314132309.png

咱們在原型上定義一個屬性,那麼實例上也就能夠「繼承」這個屬性:繼承

20190314133215.png

proto 隱式原型

實例經過 __proto__ 訪問到原型,因此若是是實例,那麼就能夠經過這個屬性直接訪問到原型:圖片

20190314141947.png

因此這二者是等價的:原型鏈

20190314142041.png

constructor 構造函數

既然構造函數經過 prototype 來訪問到原型,那麼原型也應該可以經過某種途徑訪問到構造函數,這就是 constructor:

20190314142246.png

所以二者的關係應該是這樣:

20190314142755.png

注意這裏的 constructor 是原型的一個屬性,Constructor 指的纔是真正的構造函數。二者名字不要弄混了😀

實例、構造函數、原型之間的關係

這裏咱們能夠看到若是實例想要訪問構造函數,那麼應當是:

20190314143125.png

沒有從實例直接訪問到構造函數的屬性或方法:

20190314143254.png

實例與原型則是經過上文中提到的 __proto__ 去訪問到。

在讀取一個實例的屬性的過程當中,若是屬性在該實例中沒有找到,那麼就會循着 __proto__ 指定的原型上去尋找,若是還找不到,則嘗試尋找原型的原型🐚:

20190314143837.png

咱們把註釋刪掉,給實例同名屬性,能夠看到打印出來的屬性就指向這個:

20190314143944.png

原型鏈

原型一樣也能夠經過 __proto__ 訪問到原型的原型,比方說這裏有個構造函數 Person 而後「繼承」前者的有一個構造函數 People,而後 new People 獲得實例 p

當訪問 p 中的一個非自有屬性的時候,就會經過 __proto__ 做爲橋樑鏈接起來的一系列原型、原型的原型、原型的原型的原型直到 Object 構造函數爲止。

這個搜索的過程造成的鏈狀關係就是原型鏈

20190314144733.png

以下圖:

20190314145239.png

看到 null 了麼,原型鏈搜索搜到 null 爲止,搜不到那訪問的這個屬性就是不存在的:

20190314145540.png

以上,這就是原型、原型鏈、構造函數、實例、null 之間的關係。

相關文章
相關標籤/搜索