JavaScript是一門基於原型的語言,在JavaScript中沒有類的定義,而是使用原型和原型鏈來實現模擬實現類和類的繼承的關係(ES6的類也只是語法糖)。什麼是原型呢?
這個網紅布丁小兔子,很可愛吧,是怎麼作出來的呢?
首先調好布丁原料,而後拿出模具,將原料倒入,等待成型以後,輕輕的取出來,最後將成型的兔子的耳朵和鼻子圖上紅色,眼睛塗上黑色,就大功告成啦。這個時候就能夠拿出手機拍照發朋友圈。。。跑偏了。。。javascript
JavaScript 常被描述爲一種基於原型的語言 (prototype-based language)——每一個對象擁有一個原型對象,對象以其原型爲模板、從原型繼承方法和屬性。
以上摘自MDN上對原型的一句描述。咱們回頭看咱們只作兔子布丁的這個過程,咱們以模具(原型對象)
爲模板,成型(繼承了原型的形狀這個屬性)
以後取出,給兔子的耳朵和鼻子上色(實現了本身的方法和屬性)
。
在JS中,對象都會包含一個屬性__proto__指向了它的原型。全部會有({}).__proto__ === Object.prototype
,同時也能夠經過({}).__proto__.constructor
找到Object
。
讀了上面這段話,又引出了一個問題,prototype
又是什麼東西?java
在javascript中,函數能夠有屬性。 每一個函數都有一個特殊的屬性叫做原型(prototype)。
mdn中有這樣一段話,是的,prototype
是在生成函數時,自動添加上去的一個屬性。函數
在傳統的 OOP 中,首先定義「類」,此後建立對象實例時,類中定義的全部屬性和方法都被複制到實例中。在 JavaScript 中並不如此複製——而是在對象實例和它的構造器之間創建一個連接(它是__proto__屬性,是從構造函數的prototype屬性派生的),以後經過上溯原型鏈,在構造器中找到這些屬性和方法。
在JS中沒有類的概念,那麼是怎麼實現類和繼承的呢?
從上面的圖中能夠看到一條鏈式關係 s.__proto__.__proto__ === Object.prototype
,JS正是經過__proto__
和prototype
的這種依賴關係實現了原型鏈和繼承。能夠把這種鏈式關係想象成是長城,每一個烽火臺就是從前面的烽火臺繼承獲得的實例,在當前烽火臺沒有找到想要的屬性時,就會順着道路(原型鏈)
去到前一個烽火臺找,直到到達終點(Object.prototype)
或者是找到爲止。
spa
__proto__
的屬性指向它對應的原型prototype
屬性__proto__
和prototype
的合做實現的obj.__proto__ === Constructor.prototype
obj.__proto__.constructor === Construtor