一直對JavaScript的原型與繼承不瞭解,參考《JavaScript權威指南(第六版)》和《JavaScript高級程序設計(第三版)》對這個點的知識作個整理,方便本身記憶。如下內容大部分摘錄自這兩本書前端
每個JavaScript對象都有與之相關的原型對象(prototype)。函數
JavaScript對象會繼承原型對象的屬性。this
首先咱們先了解下建立對象基本的方式:spa
//1,對象直接量 var a={},b={m:1} //2,構造函數 var c=new Object(),d=new Date(); //3,Object.create(param); var x=Object.create(d);
1.使用對象直接量建立的對象使用Object.prototype做爲它們的原型對象;prototype
2.經過new建立的對象以構造函數的prototype屬性做爲原型對象;設計
3.經過Object.create()建立的對象使用第一個參數做爲它們的原型對象;code
說明:任何函數均可以是構造函數,好比有一個函數F,當使用 var f=new F()建立對象時,F就是對象f的構造函數;其餘狀況下F就是一個普通的函數對象
除了經過Object.create()建立的對象的原型是咱們本身指定的外,Object.prototype和構造函數的prototype屬性又是怎麼來的呢?blog
1.Object.prototype是JavaScript內置的原型對象,定義了toString,valueOf等方法及一些屬性。當咱們經過var a={}建立對象a,雖然咱們沒有爲a定義toString方法,可是當咱們調用a.toString()的時候會返回"[object Object]",這是由於這個方法已經在Object.prototype定義了。
繼承
2.當咱們建立函數的時候,JavaScript就會爲該函數建立一個prototype屬性。請看代碼:
function F(){} console.info(F.prototype);//{constructor: ƒ} console.info(F.prototype.constructor===F);//true
先了解一下JavaScript對象原型的例外,在JavaScript中有少數對象是沒有原型對象的。
1.Object.prototype
2.null
3.經過Object.create(null)建立的對象;
除上述對象外,全部的JavaScript對象默認都有一個原型對象。原型對象也是一個對象實例,若是它不屬於上述3類對象,那麼它也有本身的原型對象。好比a的原型對象是b,b的原型對象是c,c的原型對象是d……直到遇到上述3類沒有原型對象的對象,從而在a,b,c,d……之間構成了一個鏈,a-->b-->c-->d……,這就是原型鏈。
當在a中尋找一個屬性,若是有返回屬性值;若是沒有就去b中找,有就返回屬性值;若是沒有就去c中找……,若是找到鏈的末端,還沒找到就返回undefined。即經過原型鏈,實現了對象對原型鏈上的對象的繼承。
說明:處在原型鏈前端的屬性會隱藏後面對象的同名屬性。好比:查找屬性x,b和c中都有屬性x,a.x的值等於b.x,而c中的x被隱藏了。
構造函數有默認的原型對象,這個原型對象的原型對象是Object.prototype。那麼,經過new加構造函數建立對象,原型鏈上只會有三個對象,如何擴展這個原型鏈呢?請看代碼:
//本段代碼來自於《JavaScript高級程序設計(第三版)》163頁
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //繼承了 SuperType SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){ return this.subproperty; }; var instance = new SubType(); alert(instance.getSuperValue()); //true
紅色代碼處,咱們修改了SubType函數的prototype屬性的指向,使它指向了SuperType的一個對象實例。這個當咱們經過new SubType()建立對象instance時,instance的原型對象是SuperType實例,而SuperType實例的原型對象是SuperType.prototype,SuperType.prototype的原型對象是Object.prototype。這樣咱們就擴展了對象instance的原型鏈。進而,咱們也能夠把SuperType.prototype設置爲別的對象實例而再次擴展原型鏈。以此類推,咱們能夠無限擴展原型鏈。
能夠看到經過原型鏈,能夠在JavaScript中實現簡單的繼承:對象會繼承本身原型鏈上的對象的屬性。關於繼承更進一步的知識請看《JavaScript高級程序設計(第三版)》6.3繼承一節,講的很詳細。
以上就是對JavaScript原型最簡單的總結。請各路大俠批評指正!