淺談js框架設(shè)計 在這個JavaScript框架隨處亂跑的時代,你是否考慮過寫一個自己的框架?下面的內(nèi)容也許會有點幫助。
創(chuàng)新互聯(lián)主要從事成都做網(wǎng)站、成都網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)慶安,十年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220
一個框架應(yīng)該包含哪些內(nèi)容?
1.語言擴(kuò)展
大部分現(xiàn)有的框架都提供了這部分內(nèi)容,語言擴(kuò)展應(yīng)當(dāng)是以ECMAScript為基礎(chǔ)進(jìn)行的,不應(yīng)當(dāng)依賴任何宿主環(huán)境,也就是說,作為一個框架的設(shè)計者,你應(yīng)當(dāng)保證你的語言擴(kuò)展可以工作在任何宿主環(huán)境中,而不是僅僅適合瀏覽器環(huán)境。你必須保證把它放到WScript,SpiderMonkeyShell,Rhino Shell,Adobe ExtendScript Toolkit甚至FlashActionScript等環(huán)境中都能正確的工作,舉個現(xiàn)實一點的例子setTimeout不可以出現(xiàn)在其中,你也不能用XMLHTTP加載腳本運行,盡管它們看起來很貼近語言。保持這一部分的獨立性可以讓你方便的移植你的框架到其他宿主環(huán)境下?!?/p>
2.數(shù)據(jù)結(jié)構(gòu)和算法
JS本身提供的內(nèi)置對象非常有限,很多時候,框架應(yīng)該提供一些數(shù)據(jù)結(jié)構(gòu)和算法來幫助使用者更好的完成邏輯表達(dá)。但我認(rèn)為隨便翻本數(shù)據(jù)結(jié)構(gòu)或者算法書用JS挑幾個實現(xiàn)了加到框架中是不負(fù)責(zé)任的,多數(shù)數(shù)據(jù)結(jié)構(gòu)應(yīng)當(dāng)以庫的形式存在而非框架??蚣苤械臄?shù)據(jù)結(jié)構(gòu)應(yīng)該足夠常用而且實現(xiàn)不是非常復(fù)雜的,可以考慮的如集合、哈希表、鏈表、有序數(shù)組以及有序數(shù)組上的二分搜索。對JS來說,對象是一個天然的字符串哈希表,而集合很容易在哈希表上實現(xiàn),因此只需要處理掉Object的內(nèi)置方法,我們就可以實現(xiàn)一個高效的集合或哈希表。
3.DOM擴(kuò)展
JS主要應(yīng)用于Web開發(fā),目前所有的框架也都用于瀏覽器環(huán)境,那么,瀏覽器端環(huán)境里重點中的重點DOM當(dāng)然也是框架的擴(kuò)展目標(biāo)了,如果一個框架不提供DOM的擴(kuò)展,那么其實基本沒什么用處了。需要注意的是,DOM擴(kuò)展也有w3c的標(biāo)準(zhǔn)可依,所以,不要嘗試為各種瀏覽器做一些奇怪的擴(kuò)展,比如FF下面的element們的prototype,框架的編寫者應(yīng)當(dāng)無視它們。DOM擴(kuò)展的主要任務(wù)之一是兼容性,不同瀏覽器上的DOM實現(xiàn)相差很多,框架必須消除這些實現(xiàn)帶來的差異,提供統(tǒng)一的訪問方式。當(dāng)然,做為框架,應(yīng)當(dāng)提供一些更為方便的接口,將宿主提供的DOM對象用js對象封裝是個不錯的想法,但是同時這也很可能會造成內(nèi)存泄露,所以做這事之前,了解內(nèi)存泄露是必要的。實際上,自己想象的擴(kuò)展遠(yuǎn)不如W3C的設(shè)計,比如如果你能更完整地實現(xiàn)XPath,你就能比JQuery做的更好。
4.AJAX擴(kuò)展
大部分現(xiàn)有框架出現(xiàn)的原因都是因為AJAX,所以如果你想設(shè)計一個受歡迎的框架,AJAX是必須要做的。跟DOM擴(kuò)展很相似,AJAX擴(kuò)展的主要任務(wù)是兼容和內(nèi)存泄露,對AJAX的核心組件XMLHttpRequest對象,必須在IE6中使用ActiveX創(chuàng)建,而ActiveX又有各種版本,而隨之而來的內(nèi)存泄露和兼容性變得非常麻煩,比如:事件函數(shù)名大小寫、this指向、事件函數(shù)的null賦值。處理好這些兼容性的基礎(chǔ)上,可以做進(jìn)一步的工作,提供一些常用的實現(xiàn)。應(yīng)該指出的是,除非你確定你提供的接口比原來的更好,否則不要改變原來的XMLHttpRequest對象的接口,比如寫一個Request函數(shù)來代替open和send,如果你不清楚W3C的專家們?yōu)槭裁催@么設(shè)計,請不要把他們想象成傻瓜。我想自己另外寫一個兼容且內(nèi)存安全的XMLHttpRequest加入到自己框架的命名空間里,使它從外部看上去跟W3C描述的XMLHttpRequest一模一樣是不錯的辦法,對XMLHttpRequest我認(rèn)為唯一可以考慮的修改是提供onsuccess事件。當(dāng)然針對一些復(fù)雜功能的AJAX擴(kuò)展也是可行的,比如HTMLHttpRequest類似的擴(kuò)展可以讓AJAX初學(xué)者喜歡你的框架。
5.效果
時間效果是最能刺激用戶神經(jīng)的,漸隱、緩動、滑動、顏色漸變這些都很不錯,其實技術(shù)難度也不是很高。拖動效果則是瀏覽器中一個很重要的效果,用鼠標(biāo)事件來模擬本來很容易,不過兼容和setCapture也是很麻煩的事情。這一部分內(nèi)容量力而為就可以了。
7.腳本管理
因為大家非常喜歡C++風(fēng)格的include或者JAVA風(fēng)格的import,很多框架提供了基于AJAX的腳本管理,不過同步加載的效率問題是巨大的。之前我們曾經(jīng)作過各種嘗試,希望找到一個瀏覽器中不用XMLHTTP加載外部js的方法,但是最后得出的結(jié)論是:不可能。
關(guān)于這個,略微思考就可以知道,Java C++ C#都是編譯型語言,include 和import都是編譯期處理,在js中做到類似的事情是不太可能的。為了實現(xiàn)類似的功能,我想我們可以利用服務(wù)端程序或者編寫一個文本工具來實現(xiàn)。
YUI將所有的js文件依賴關(guān)系提取出來的做法是可行的,不過這不能算是include的實現(xiàn)方式了,維護(hù)依賴關(guān)系不是一件很簡單的事情。
8.控件
EXT的成功告訴我們:提供優(yōu)質(zhì)的控件才是框架的王道。你不能指望優(yōu)質(zhì)的擴(kuò)展會吸引更多使用者。多數(shù)人只關(guān)心如何快速完成手邊的工作。當(dāng)然不是所有框架都要提供這部分內(nèi)容??丶脡娜Q于能力和美工,不過至少要保證框架里的控件不會內(nèi)存泄露。
框架設(shè)計的若干原則:
1.不要做多余的事
對這框架設(shè)計來說,我認(rèn)為一個非常必要的原則就是不要做多余的事情,舉個極端的的例子:
function add(a,b)
{
return a+b;
}
這樣的代碼如果出現(xiàn)在框架中,就是個十足的笑話。不過大多數(shù)時候,事情不是那么明顯,很多框架試圖用某種形式在JS中"實現(xiàn)"OOP,但是實際上,JS本身是OO的(ECMA262中明確指出來的,不像某些人所說是基于對象云云)只是有一些語法跟Java等語言不同。那么顯然這些OOP的"實現(xiàn)"其實是跟上面的例子一樣的道理。另一個例子是Array.prototype.clone
Array.prototype.clone=function(){
return this.slice();
}
2.慎用prototype擴(kuò)展
很多框架利用修改原生對象的prototype來做語言擴(kuò)展,但我認(rèn)為應(yīng)當(dāng)小心地看待這件事,毫無疑問這將造成一定的命名污染,你無法保證框架的使用者或者與你的框架共存的其他框架不會使用同樣的名字來完成其他的事情。特別需要注意的是,Object和Array這兩個對象的prototype擴(kuò)展格外的危險,對Object來說,如果Object被修改,那么框架的使用者將無法創(chuàng)建一個未被修改的干凈的對象,這是一個致命的問題,尤其如果你的使用者喜歡用forin來反射一個對象的屬性。Array.prototype修改的危險來自js一個不知有意還是無意的小小設(shè)計,對原生的Array來說,任何情況下for和forin的遍歷結(jié)果是相同的,而因為無法控制自定義的屬性是不可枚舉的,任何Array.prototype的修改都會破壞這種特性。一方面,我認(rèn)為不應(yīng)當(dāng)推薦用forin遍歷數(shù)組,這其中包含著錯誤的語義。另一方面,框架的設(shè)計者必須尊重這些使用者,因為對于ECMA所定義的語法而言,它是正確的做法。其中包含著這樣一個簡單的事實:假如你的框架中修改了Array.prototype,那么一些之前能正確工作的代碼變得不可正確工作。
直接修改prototype看上去非常誘人,但是在考慮它之前應(yīng)當(dāng)先考慮兩種可能的方案:
(1)函數(shù)
提供一個以對象為第一個參數(shù)的函數(shù)比如 Array.prototype.each =
function ForEach(arr,f)
{
if(arr instanceof Array)/*...*/;
}
(2)繼承
以return的形式繼承一個內(nèi)置對象 比如考慮Array.prototype.each=
function ArrayCollection()
{
var r=Array.apply(this,arguments);
r.each=function(){/*......*/};
return r;
}
套用一句名言,不要修改原生對象的prototype,除非你認(rèn)為必要。不過修改原生對象的prototype確實有一些特殊的用途(就是"必要的情況"),主要體現(xiàn)在2點:文字量支持和鏈?zhǔn)奖磉_(dá)。舉一個例子可以體現(xiàn)這兩點:
var cf=function f(a,b,c,d)
{
/*........*/
}.$curry(3,4).$curry(5).$run();
如果希望實現(xiàn)類似上面的表達(dá)方式,可能就需要擴(kuò)展Function.prototype,權(quán)衡一下的話,如果你認(rèn)為命名污染的代價是值得的,那么也是可以提供給使用者的。
一個比較討巧的辦法是把選擇權(quán)利交給使用者,提供一個擴(kuò)展器:
function FunctionExtend()
{
this.$curry=function(){/*......*/};
this.$run=function(){/*......*/};
}
如果用戶喜歡可以FunctionExtend.apply(Function.prototype); 如果不喜歡擴(kuò)展 則可以
var r=function(){/*......*/};
FunctionExtend.apply(r);
3.保持和原生對象的一致
不知你有沒有注意到,內(nèi)置對象Function Array等都有這樣的性質(zhì):
new Function()跟Function的結(jié)果完全一致(String Number Boolean這種封裝型對象沒有這樣的性質(zhì))
如果框架中提供的類也具有這種性質(zhì),會是不錯的選擇。這僅僅是一個例子,如果你注意到了其他細(xì)節(jié),并且讓框架中的類和原生對象保持一致,對使用者來說是非常有益的。
4.尊重語言 尊重用戶
編寫框架應(yīng)該尊重依賴的語言環(huán)境,在對原有的元素修改之前,首先應(yīng)該考慮到原來的合理性,任何語言的原生環(huán)境提供的都是經(jīng)過了精心設(shè)計的,在任何修改之前,至少應(yīng)該考慮這幾點:效率、命名規(guī)范、必要性、與其他功能是否重復(fù)。如果你沒有付出至少跟語言的設(shè)計者相當(dāng)?shù)墓ぷ髁?,你的做法就是欠考慮的。
編寫框架也應(yīng)該尊重用戶的所有習(xí)慣,將編寫者的喜好強加給使用者并不是框架應(yīng)該做的事情??蚣軕?yīng)該保證大部分在沒有框架環(huán)境下能運行的代碼都能在框架下正常工作,這樣用戶不必為了使用你的框架而修改原有的代碼。
5.規(guī)范命名和使用命名空間
減少命名污染可以讓你的框架跟其他框架更好地共存。很多框架使用了命名空間來管理,這是良好的設(shè)計。命名應(yīng)該是清晰且有實際意義的英文單詞,如前面3所述,為了保持和原生對象的一致,命名規(guī)則最好貼近原生對象,比如類名第一字母大寫,方法名用駝峰命名。捎帶一提prototype中的$實在是非常糟糕的設(shè)計,無法想象$出現(xiàn)的目的僅僅是為了讓使用者少寫幾個字母。這種事情應(yīng)該交給你的用戶在局部代碼中使用
《JavaScript語言精髓與編程實踐第三版周愛民》百度網(wǎng)盤pdf最新全集下載:
鏈接:
?pwd=ohdu 提取碼:ohdu
簡介:JavaScript 是一門包含多種語言特性的混合范型語言,在面向?qū)ο蠛秃瘮?shù)式語言特性方面表現(xiàn)尤為突出,且在 ES6 之后所添加的并行語言特性也極為出色?!禞avaScript語言精髓與編程實踐(第3版)》基于 ES6,并涵蓋 ES2019 規(guī)范,全面講述 JavaScript 在五個方面的語言特性,以及將這些特性融會如一的方法。本書不但完整解析了 JavaScript 語言,還逐一剖析了相關(guān)特性在多個開源項目中的編程實踐與應(yīng)用,是難得的語言學(xué)習(xí)參考書。
本書作者在前端開發(fā)領(lǐng)域經(jīng)驗豐富、深耕不輟,一書三版,歷經(jīng)十余年。書中對 JavaScript 語言的理解與展望,尤其適合期望精通這門語言的中高級程序員和語言實踐者閱讀。 ?
《JavaScript基礎(chǔ)教程(第9版)》([美] Dori Smith)電子書網(wǎng)盤下載免費在線閱讀
資源鏈接:
鏈接:
提取碼:8ghp
書名:JavaScript基礎(chǔ)教程(第9版)
作者:[美] Dori Smith
譯者:陳劍甌
出版社:人民郵電出版社
出版年份:2015-3
頁數(shù):404
內(nèi)容簡介:本書是經(jīng)典的JavaScript入門書,以易學(xué)便查、圖文并茂、循序漸進(jìn)和善于用常見任務(wù)講解語言知識而著稱。書中從JavaScript語言基礎(chǔ)開始,分別討論了圖像、框架、瀏覽器窗口、表單、正則表達(dá)式等內(nèi)容,循序漸進(jìn)地給出了JavaScript以及相關(guān)的CSS、DOM、Ajax和jQuery等技術(shù)。第9版全新改寫,新增更多示例和技術(shù)介紹,使用流行的jQuery框架向網(wǎng)站輕松添加有用的功能。
本書適合有志于從事Web開發(fā)和設(shè)計的初學(xué)者.也是高等院校相關(guān)課程的理想入門教材。
作者簡介:Dori Smith
世界知名的Web程序員和設(shè)計師,從事軟件開發(fā)已有20多年。她是Web標(biāo)準(zhǔn)項目(WaSP)指導(dǎo)委員會委員,并發(fā)起成立了世界性的女性技術(shù)社區(qū)Wise-Women Web。
Tom Negrino
蜚聲全球的技術(shù)作家,長期主持Macworld和許多其他技術(shù)雜志的專欄。自1995年開始,與Dori Smith合作著書,向初學(xué)者介紹Web,目前已著有數(shù)十本書。