標籤:pre -- tostring 知識 string 建立對象 原型鏈 super target
一直對JavaScript的原型與繼承不瞭解,參考《JavaScript權威指南(第六版)》和《JavaScript進階程式設計(第三版)》對這個點的知識做個整理,方便自己記憶。以下內容大部分摘錄自這兩本書
每一個JavaScript對象都有與之相關的原型對象(prototype)。
原型對象有什麼用?
JavaScript對象會繼承原型對象的屬性。
原型對象是從哪裡來的?
首先我們先瞭解下建立對象基本的方式:
//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作為它們的原型對象;
2.通過new建立的對象以建構函式的prototype屬性作為原型對象;
3.通過Object.create()建立的對象使用第一個參數作為它們的原型對象;
說明:任何函數都可以是建構函式,比如有一個函數F,當使用 var f=new F()建立對象時,F就是對象f的建構函式;其他情況下F就是一個普通的函數
除了通過Object.create()建立的對象的原型是我們自己指定的外,Object.prototype和建構函式的prototype屬性又是怎麼來的呢?
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;}//繼承了 SuperTypeSubType.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原型最簡單的總結。請各路大俠批評指正!
JavaScript中的原型與原型鏈