相信每個前端工程師都有自己喜愛的javascript框架,說情感也好,道信仰也罷, javascript框架帶給人的不僅僅是便捷的開發,更有一種純粹的邏輯美感,不管是jquery曼妙的簡潔,還是yui魔術般的沙箱,都使我們產生無窮的想像。然而,js框架卻又必然無法做到面面俱到的完美無瑕,例如jquery在OO方面做出的讓步,以及yui在性能上做的犧牲,無不給人傳達一種缺憾美、一種理想的現實主義。今天,我們來看看yui3在框架設計中的這些犧牲和讓步,以便讓我們更加深刻的理解yui3的全貌,並將其優勢發揮至最佳。
1.種子的一步到位or 顆粒化
所謂種子一步到位是指只要在頁面引入一個種子檔案的script標籤,例如prototype和jquery,只要引入一個prototype.js或jquery.js就可以了,他們將各自對dom操作和event的封裝等等都囊括進一個文件中,並盡力將其做到最小,這樣做的好處是顯而易見的,使用框架非常簡單。然而yui將這些功能做了級別劃分和顆粒化設計,從概念上抽像出來“核心”、“工具”和“組件”,每個小功能放在一個文件當中,需要的時候則要自行去引用, yui文件中給出的大量demo都採用這種方法,這種設計顯然不像jquery那樣對初學者友好,而且使用起來不夠傻瓜,為了實現一個小功能,甚至要引入三四個js文件。 yui這樣做的原因有兩個,一是yui實在太大,把所有功能都搞進一個文件中確實有點不靠譜,二是為其動態加載的框架設計做鋪墊。
2、手動引入or 動態加載
往頁面中寫js的傳統方法是,直接將js檔案當作script標籤路徑寫在頁面中,使用yui也可以這樣引入頁面,但yui更建議使用loader進行動態載入。動態載入腳本的淵源很複雜,目前來看主要原因有三,其一,頁面中手寫js標籤無論如何都會佔用一個http請求,即使這個請求是一個304,動態加載的文件緩存後則不必發起真實的http請求,其二,動態加載可以實現按需加載,而且可以根據js文件之間的依賴進行去重和排序,手寫標籤加載js文件則必須讓開發者去額外關註一下文件的排序、重複等等,其三,動態載入有利於頁面程式碼的語義化,這使得開發者只關心“需要什麼”,而不用去在意“如何得到”。當專案變得越發臃腫,維護成本越來越高的時候,這中小技巧會有不小的好處的。
3.邏輯啟動的單一入口or 沙箱
我們在頁面中啟動一個js邏輯通常是放在一個類似onDomReady的方法中,如果頁面中存在多個邏輯的時候怎麼辦呢?例如,a實作了邏輯A,頁面程式碼是這樣的
<script src="logicA.js" />
<script>
$.onDomReady(function(){
___LogicA.start();
});
</script>
這段程式碼通常寫在頁面的尾部,這段邏輯所伴隨的html程式碼是埋藏在頁面的某處,這時b要在頁面中增加邏輯B,b的做法是先找到尾部的這段程式碼,然後更改成如下模樣:
<script src="logicA.js" />
<script src="logicB.js" />
<script>
$.onDomReady(function(){
___LogicA.start();
___LogicB.start();
});
</script>
同樣,B邏輯所伴隨的html程式碼也是埋藏在頁面的某處,這樣看來,js邏輯和其伴隨的html程式碼如此分離,以至於到了刪減功能的時候,往往刪掉html卻忘了刪js ,或是刪掉js忘了刪除html,在重用程式碼的時候也會是個麻煩。同樣,在調試的時候,工程師也要打開兩個視窗分別關注js和html,即使這兩段程式碼在同一個檔案當中。如此則不如把程式碼寫成這樣:
這種coding寫法正是yui所提倡的,也就是所謂的沙箱,每個邏輯都包含在一個沙箱中,各司其則互不干擾。當第三者瀏覽程式碼的時候也立刻明白這就是一個獨立的功能塊,包含典型的html結構和啟動邏輯的js,要重複使用,整塊拷走即可。
<!–A邏輯的html程式碼片段–>
<script src="logicA.js" />
<script>
$.onDomReady(function(){
___LogicA.start();
});
</script>
…
<!–B邏輯的html程式碼片段–>
<script src="logicB.js" />
<script>
$.onDomReady(function(){
___LogicB.start();
});
</script>