讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議83:使用原型委託 >

建議83:使用原型委託

任何一個對象都連接到一個原型對象,並且可以從中繼承屬性。通過對像字面量創建的對象都可以連接到Object.prototype這個基本原型對象,例如:


var obj={};

Object.prototype.name="prototype";

obj.name;//"prototype"


當然,在創建一個新對像時也可以選擇某個對象作為它的原型。JavaScript提供的實現機制比較煩瑣,不妨設計一個中間件,以簡化這種操作:為Object對像增加一個create方法,由create方法創建一個使用參數對像作為其原型的新對象。


if(typeof Object.create!=='function'){

Object.create=function(o){

var F=function{};

F.prototype=o;

return new F;

};

};


在上面代碼中先檢測Object.create是否為Object對象的方法,如果不是,則添加該方法,在該方法內創建一個構造器,把參數對像作為原型傳遞給它,然後實例化構造器,最後將這個實例返回。

現在就可以定義兩個對像obj1和obj2,借助Object.create這個中間件,把obj1作為prototype綁定到obj2上,此時就可以在obj2中繼承obj1對像中的屬性了。


var obj1={

name:"obj1"

}

var obj2=Object.create(obj1);

obj2.name;//"obj1"


原型連接在更新時是不起作用的。當改變某個對象屬性值時,不會觸及該對象的原型,例如:


obj2['first-name']='first';

obj2['middle-name']='middle';

obj2.name='More';


原型連接只有在檢索值時才會用到。如果嘗試去獲取對象的某個屬性值,並且該對像沒有此屬性名,那麼JavaScript會試著從原型對像中獲取屬性值。如果原型對象也沒有該屬性,那麼再從原型對象的原型中尋找,依此類推,直到該過程最後到達終點Object.prototype。如果想要的屬性完全不存在於原型鏈中,那麼最後結果將返回undefined值。這個檢索的過程稱為原型委託。

原型關係是一種動態的關係。如果添加一個新的屬性到原型中,那麼該屬性會立即被所有基於該原型創建的對象繼承。