輕量級(jí)前端MVVM框架avalon:整體架構(gòu)
官網(wǎng)提供架構(gòu)圖
單看這個(gè)圖呢,還木有說明,感覺有點(diǎn)蛋疼,作者的抽象度太高了,還好在前面已經(jīng)大概分析過了執(zhí)行流程
如圖
- 左邊是View視圖,我們就理解html結(jié)構(gòu),換句話就是說用戶能看到的界面,渲染頁面,綁定事件,切換類名,什么臟活都攬
- 右邊是ViewModel 視圖模式,就是開發(fā)者通過avalon.define("xxx", function(vm){vm.firstName = "模型"})
- 既然是MVVM 那么還有個(gè)M跑哪里去了,M在MVVM定義中,M只是一個(gè)過客,被VM給再次包裝,它與其他表示業(yè)務(wù)狀態(tài)的東西融入VM(ViewModel)中,一個(gè)普通的JS對(duì)象,可能是后臺(tái)傳過來的,也可能是直接從VM中拿到 vm.firstName = "模型" 這個(gè)就是M咯,所以作者在圖中就沒體現(xiàn)出來吧
從定義ViewModel開始,掃描到vm關(guān)聯(lián)的東東 形成訪問器,好吧其實(shí)整個(gè)就這么簡單。
打開avalon源碼,我們就看到這樣的結(jié)構(gòu):
- (function(DOC) {
- 內(nèi)部代碼
- })(document);
這種基本的結(jié)構(gòu)雖然已經(jīng)被寫爛了,但是既然是分析就從來到位來一遍吧。
自調(diào)用匿名函數(shù)
jquery為例
1. 這是一個(gè)自調(diào)用匿名函數(shù)。什么東東呢?在第一個(gè)括號(hào)內(nèi),創(chuàng)建一個(gè)匿名函數(shù);第二個(gè)括號(hào),立即執(zhí)行
2. 為什么要?jiǎng)?chuàng)建這樣一個(gè)“自調(diào)用匿名函數(shù)”呢?
通過定義一個(gè)匿名函數(shù),創(chuàng)建了一個(gè)“私有”的命名空間,該命名空間的變量和方法,不會(huì)破壞全局的命名空間。這點(diǎn)非常有用也是一個(gè)JS框架必須支持的功能,jQuery被應(yīng)用在成千上萬的JavaScript程序中,必須確保jQuery創(chuàng)建的變量不能和導(dǎo)入他的程序所使用的變量發(fā)生沖突。
3. 匿名函數(shù)從語法上叫函數(shù)直接量,JavaScript語法需要包圍匿名函數(shù)的括號(hào),事實(shí)上自調(diào)用匿名函數(shù)有兩種寫法
- 寫法1
- (function() {
- console.info( this );
- console.info( arguments );
- }( window ) );
- 寫法2
- (function() {
- console.info( this );
- console.info( arguments );
- })( window );
4.為什么要傳入window呢?
通過傳入window變量,使得window由全局變量變?yōu)榫植孔兞?,?dāng)在jQuery代碼塊中訪問window時(shí),不需要將作用域鏈回退到頂層作用域,這樣可以更快的訪問window;這還不是關(guān)鍵所在,更重要的是,將window作為參數(shù)傳入,可以在壓縮代碼時(shí)進(jìn)行優(yōu)化,看看jquery- 1.6.1.min.js:
- (function(a,b){})(window); // window 被優(yōu)化為 a
5.為什么要在在參數(shù)列表中增加undefined呢?
在 自調(diào)用匿名函數(shù) 的作用域內(nèi),確保undefined是真的未定義。因?yàn)閡ndefined能夠被重寫,賦予新的值。
- undefined = "now it's defined";
- alert( undefined );
瀏覽器測試結(jié)果:
6.注意到源碼最后的分號(hào)了嗎?
分號(hào)是可選的,但省略分號(hào)并不是一個(gè)好的編程習(xí)慣;為了更好的兼容性和健壯性,請(qǐng)?jiān)诿啃写a后加上分號(hào)并養(yǎng)成習(xí)慣。
總體架構(gòu)
按代碼結(jié)構(gòu)
- (function(DOC) {
- //命名空間
- avalon = function(el) {
- return new avalon.init(el);
- };
- //avalon掛在工具函數(shù)
- // 迷你jQuery對(duì)象的原型方法
- //css操作相關(guān)的方法
- //ecma262兼容補(bǔ)丁
- //nextTick 高級(jí)定時(shí)器
- //Observable 觀察者模式
- //Define 模型定義方法
- //Parse 解析求值函數(shù)與執(zhí)行作用域
- //Scan 節(jié)點(diǎn)掃描
- //Bind html自定義標(biāo)簽綁定處理方法
- })(document);
整個(gè)結(jié)構(gòu)基本如上。
以后會(huì)分析具體的每個(gè)實(shí)現(xiàn),源碼分析盡量到行……