JavaScript原型梳理

JavaScript中原型這個概念很常常被提起,那麼它究竟是什麼呢,它又有什麼用呢?接下來讓咱們一步一步來理解它。javascript

認識原型

原型的概念

在JavaScript中,原型也是一個對象,經過原型能夠實現對象的屬性繼承,JavaScript的對象中都包含了一個[[Prototype]]內部屬性,這個屬性所對應的就是該對象的原型。html

原型訪問器

[[Prototype]]做爲對象的內部屬性,是不能被直接訪問的。不過咱們能夠經過下面這幾種方式來獲取到原型。java

  • __proto__
  • Object.getPrototypeOf
  • obj.constructor.prototype

那麼可能會有人疑惑,平時咱們能夠經過函數的prototype屬性來獲取對象原型,這個又是怎麼回事?好吧,讓咱們看個例子。git

function Foo () {}
const f1 = new Foo()
const f2 = new Foo()
複製代碼

從上面的圖咱們能夠看出f1f2對象的__proto__屬性是指向原型對象的Foo.prototypegithub

同時這邊也回答了爲何函數的prototype能夠獲取到對象原型,這是由於函數中有prototype這個屬性,它是指向原型對象的。閉包

原型對象中也有constructor屬性指向Foo這個構造函數。因此能夠用第三種方式來獲取到對象原型,不過這個方法不可靠,由於屬性能夠變嘛。函數

總結下:ui

每一個構造函數都有一個原型對象(prototype),原型對象都包含一個指向構造函數的指針(constructor),而實例都包含一個指向原型對象的內部指針(proto)。spa

這邊拋出兩個問題:prototype

  1. 上面說到原型也是一個對象,那麼它確定也有原型的,它的原型又是指向什麼呢?
  2. 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
複製代碼

參考資料

相關文章
相關標籤/搜索