目前,Ajax技術(shù)發(fā)展勢頭迅猛,研發(fā)者已建立了一個調(diào)用大量客戶端JavaScript、不斷增長的、復(fù)雜的系統(tǒng)。因此,在JavaScript上嘗試OO技術(shù)便成為了管理復(fù)雜性的一種手段。在此過程中,多數(shù)研發(fā)者非常快便認(rèn)識到:JavaScript是一種原型化的(prototypical)語言,他缺少OO自身帶來的多種便利。
幾乎每位在研發(fā)JavaScript時嘗試應(yīng)用面向?qū)ο蠹夹g(shù)的研發(fā)者,或多或少都會問自己一個問題:“怎么調(diào)用父類(super class)的方法?”在Ajax技術(shù)還沒有目前這樣炙手可熱之前,這種問題非常少出現(xiàn),因?yàn)榇蠖鄶?shù)研發(fā)者僅在進(jìn)行客戶端form驗(yàn)證或簡單的DHTML/DOM操作時使用JavaScript。在那些簡單的解決方案中,函數(shù)式編程(functional programming)是非常有意義的,面向?qū)ο缶幊虅t處在次之重要的位置。
目前,Ajax技術(shù)發(fā)展勢頭迅猛,研發(fā)者已建立了一個調(diào)用大量客戶端JavaScript、不斷增長的、復(fù)雜的系統(tǒng)。因此,在JavaScript上嘗試OO技術(shù)便成為了管理復(fù)雜性的一種手段。在此過程中,多數(shù)研發(fā)者非常快便認(rèn)識到:JavaScript是一種原型化的(prototypical)語言,他缺少OO自身帶來的多種便利。
OO設(shè)計的主旨和關(guān)于他的一些話題談起來非常大,但只著眼于Class的定義方式,我認(rèn)為他是JavaScript研發(fā)者嘗試解決問題的最佳選擇。因此,你能在互連網(wǎng)上找到許多不同的問題解決案例,但在我看過他們后不免有些失望??這些案例都是在某個場合下適用,而不是放之四海而皆準(zhǔn)的通法。而我對這個話題的興趣來自于我的team在研發(fā) ThinWire Ajax Framework 的影響。
由于這個框架生成出對客戶端代碼的需求,才使我們“被迫”去實(shí)現(xiàn)可靠的、支持父類方法調(diào)用的OO模式。通過父類調(diào)用,你能進(jìn)一步依靠類的繼承特性來核心化通用代碼,從而更易于減少重復(fù)代碼,去掉客戶端代碼的壞味道。
下面羅列出了一些在我的研究過程中遇見的解決方式。最終,我沒有從中找出一個能接收的解決方案,于是我不得不實(shí)現(xiàn)一個自己的解決方案,你將在本文的結(jié)尾部分看到這個方案。
然而父類調(diào)用在這里是最重要的OO機(jī)制,因此我需要一個相應(yīng)的工作模式,也正是因?yàn)樵谖业挠^點(diǎn)中原型化方式是丑陋的,所以我更需要一種更加自然地使用JavaScript定義類的方法。
More Solutions:
好吧,讓我們進(jìn)入討論。正如研發(fā)者所察覺的那樣,在JS中實(shí)現(xiàn)基本的繼承是非常容易的事,事實(shí)上有一些眾所周知的方法:
丑陋的Solution:
沒有進(jìn)行父類調(diào)用的簡單繼承:
// 提前寫好的JavaScript Class定義和繼承
// 當(dāng)然,這種代碼非常丑陋,散發(fā)著代碼的壞味道。
function BaseClass() {
//BaseClass constructor code goes here
}
BaseClass.prototype.getName = function() {
return "BaseClass";
}
function SubClass() {
//SubClass constructor code goes here
}
//Inherit the methods of BaseClass
SubClass.prototype = new BaseClass();
//Override the parents getName method
SubClass.prototype.getName = function() {
return "SubClass";
}
//Alerts "SubClass"
alert(new SubClass().getName());
導(dǎo)致 IE內(nèi)存泄露 的Solution:
這種實(shí)現(xiàn)方式能夠?qū)е略贗E中的內(nèi)存泄漏,你應(yīng)該盡量避免:
// 運(yùn)行時的JavaScript Class 定義和繼承
// 看上去非常傳統(tǒng),但這些腳本會導(dǎo)致在Internet Explorer中的內(nèi)存泄漏.
function BaseClass() {
this.getName = function() {
return "BaseClass";
};
//BaseClass constructor code goes here
}
function SubClass() {
//在對象實(shí)例建立時重載父類的getName方法
this.getName = function() {
return "SubClass";
}
//SubClass constructor code goes here
}
//Inherit the methods of BaseClass
SubClass.prototype = new BaseClass();
//Alerts "SubClass"
alert(new SubClass().getName());
就像我在第一個實(shí)現(xiàn)方法中所注釋的那樣,第一個實(shí)現(xiàn)方法有些丑陋,但他相比引起內(nèi)存泄漏的第二種方式便是最佳選擇了。
我把這兩種方法放在這里的目的是指出你不應(yīng)該使用他們。
|
新聞熱點(diǎn)
疑難解答
圖片精選