讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議95:慎重使用實例繼承 >

建議95:慎重使用實例繼承

對類進行實例化操作就會產生一個新的對象,這個實例對像將繼承類的所有特性和成員,而實例繼承正是對於這種實例化過程的一種概括。類繼承和原型繼承在客戶端是無法繼承DOM對象的,同時它們也不支持繼承系統靜態對像、靜態方法等。為了更直觀地說明此問題,不妨先看下面兩個示例。

(1)使用類繼承法繼承Date對像


function D{//自定義構造函數

Date.apply(this,arguments);//調用Date對象,對其進行引用,實現繼承的目的

}

var d=new D;//實例化自定義構造函數

alert(d.toLocaleString);//[object Object]


上面的示例說明,使用類繼承無法實現對靜態對象的繼承,這是因為系統對象的結構比較特殊,它不是簡單的函數體結構,對聲明、賦值和初始化等操作都進行了獨立的封裝,所以無法實現在自定義構造函數中的那種操作。

(2)使用原型繼承法繼承Date對像


function D{//自定義空構造函數

}

D.prototype=new Date;//把Date對象的實例賦值給D的原型對像

var d=new D;//實例化D

alert(d.toLocaleString);//錯誤提示


上面的示例說明了使用原型繼承也無法實現對靜態對象的繼承。不過,使用實例繼承法能夠實現對所有JavaScript核心對象的繼承。例如,在下面的示例中,把Date對象的實例化過程和方法調用封裝在一個函數中,然後返回實例對象,這樣就可以解決核心靜態對像無法繼承的問題。


function D{//封裝函數

var d=new Date;//實例化Date對像

d.get=function{//定義本地方法,間接調用Date對象的toLocaleString方法

alert(d.toLocaleString);

}

return d;//實例對像

}

var d=new D;//實例化封裝函數

d.get;//調用本地方法,返回當前本地的日期和時間


構造函數是一種特殊結構的函數,它沒有返回值,通過this關鍵字來初始化實例對象。當然,在構造函數中可以增加return語句,為其設置一個返回值,這時返回值就是new運算符執行表達式的值。因此,在構造函數中完成對類的實例化操作,然後返回實例對象,這就是實例繼承的由來。

❑使用實例繼承法能夠實現對所有對象的繼承,包括自定義類、核心對像和DOM對像等。不過也應該清楚實例繼承的缺點,它不是真正的繼承機制,僅是一種模擬方法。

❑實例繼承法無法傳遞動態參數。類的實例化操作是在封閉的函數體內實現的,不能夠通過call或apply方法來傳遞動態參數。如果繼承需要傳遞動態參數,那麼這種繼承就會帶來很多不便。

❑實例繼承只能夠返回一個對象,與原型繼承一樣,不支持多重繼承。

❑由於通過封裝的方法把對像實例化和初始化操作都封裝在一個函數體內,因此最後通過對封裝函數執行實例化操作來獲取繼承的對象。但這種做法無法真正實現繼承對象是封裝類的實例,它仍然保持與原對象的實例關係。