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