JavaScript中原型這個概念很常常被提起,那麼它究竟是什麼呢,它又有什麼用呢?接下來讓咱們一步一步來理解它。javascript
在JavaScript中,原型也是一個對象,經過原型能夠實現對象的屬性繼承,JavaScript的對象中都包含了一個[[Prototype]]
內部屬性,這個屬性所對應的就是該對象的原型。html
[[Prototype]]
做爲對象的內部屬性,是不能被直接訪問的。不過咱們能夠經過下面這幾種方式來獲取到原型。java
那麼可能會有人疑惑,平時咱們能夠經過函數的prototype
屬性來獲取對象原型,這個又是怎麼回事?好吧,讓咱們看個例子。git
function Foo () {}
const f1 = new Foo()
const f2 = new Foo()
複製代碼
從上面的圖咱們能夠看出f1
和f2
對象的__proto__
屬性是指向原型對象的Foo.prototype
。github
同時這邊也回答了爲何函數的prototype
能夠獲取到對象原型,這是由於函數中有prototype
這個屬性,它是指向原型對象的。閉包
原型對象中也有constructor
屬性指向Foo
這個構造函數。因此能夠用第三種方式來獲取到對象原型,不過這個方法不可靠,由於屬性能夠變嘛。函數
總結下:ui
每一個構造函數都有一個原型對象(prototype),原型對象都包含一個指向構造函數的指針(constructor),而實例都包含一個指向原型對象的內部指針(proto)。spa
這邊拋出兩個問題:prototype
Foo
函數也是一個對象,它的原型指向哪裏呢?要想回答這兩個問題?這邊要引入一個概念原型鏈
原型鏈做爲實現繼承的主要方法,其基本思想是利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。
仍是Foo
函數來舉例子吧。
Function Foo () {}
const f1 = new Foo()
const f2 = new Foo()
const o1 = {}
const o2 = {}
複製代碼
先來看下上面的第一個問題:
從這個原型鏈圖中能夠看出Foo.prototype
這個對象的原型是Object.prototype
。這個也應驗了全部對象都繼承自Object.prototype
。
這邊還能夠看到Object.prototype
原型是指向null
的。
接下來來看下第二個問題:
從上圖能夠看到Foo
函數的原型是指向Function.prototype
的。
不知道大家有沒注意到,Function
的原型也是指向Function.prototype
的,還有Function.prototype
指向Object.prototype
同時這邊能夠看到Objcet
也是由函數建立的,函數的原型鏈上又有Object.prototype
,這邊好像有問題,Objcet
沒被建立以前,函數原型鏈上爲何會有Object.prototype
?
這邊有一種的解釋是:
先有 Object.prototype(原型鏈頂端),Function.prototype 繼承 Object.prototype 而產生,最後,Function 和 Object 和其它構造函數繼承 Function.prototype 而產生。
順便提下函數其實也有一個constructor
屬性,它是指向Function
的。
Foo.constructor === Function // true
Array.constructor === Function // true
Function.constructor === Function // true
Object.constructor === Function // true
複製代碼
講到這裏也差很少了,出一些題給你們看看。
function Foo () {}
typeof (Object) // function
typeof (Array) // function
Foo.constructor === Function // true
Function.constructor === Function // true
Object.prototype.constructor === Object // true
({}).__proto__ === Object.prototype // true
Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true
Object instanceof Function // true
Function instanceof Object // true
typeof Object.prototype // object
typeof Function.prototype // function
複製代碼