本版本最大的改進是啓用全新的parser。html
parser是用於幹什麼的?在視圖中,咱們經過綁定屬性實現雙向綁定,好比ms-text="firstName", ms-html="sex + '士'", ms-visible="Math.abs(toggle + 2000) >= 20", 咱們須要將它們轉換爲求值函數。咱們經過ms-controller="vm"來綁定ViewModel,好比vm = { firstName: '司徒'}, 那麼對於上面的第一個綁定,咱們想讓它變成函數,之前是這樣實現的:node
function anonymous(vm1372575919386) { with (vm1372575919386) { var ret1372575919386 = firstName } return ret1372575919386 }
而後視圖刷新函數會將vm傳入此函數,var ret = anonymous(vm), 獲得'司徒',而後node.value = ret(注,這裏的node 爲文本節點,它在掃描DOM樹時被抽取出來),完成視圖的最少化刷新。這個過程當中如何將綁定屬性的值轉換爲求值函數顯然是重中之重。 git
以前的parser,正如你們看到的那樣,很是簡單,而後with表達式一包,而後返回結果。但with在ES5的嚴格模式下運行不了,也一直爲性能潔癖人士所不齒。而且它存在一個問題,它的依賴收集並不完整。好比下面這種github
aaa {{test1 && test2}} ruby
上面的插值表達式是一個文本綁定,轉換爲求值函數時,爲:框架
function anonymous(vm1372575919386) { with (vm1372575919386) { var ret1372575919386 = test1 && test2 } return ret1372575919386 }
當一開始test1爲false, test2爲true時,因爲短路與的關係,咱們並無對test2進行取值。因爲avalon只在求值函數的第一次執行時收集依賴,在依賴是經過求值賦值語句實現的,而這時,咱們就確定遺漏了test2了。所以一個全新的parser就迫在眉睫了。mvvm
新的parser的實現思路時,設法抽取到綁定值中的變量,而後轉換爲賦值語句,放到求值函數的最前面,這樣就不會遺漏任何依賴了。問題是如何獲得這些變量。好比上面三例,它們的變量依次是firstName, sex, toggle,咱們要設法去掉全部雜質,首先要去掉註釋,字符串,正則這些字面量,而後是加減乘除這些操做符,而後是if, while, for, undefined, void 等關鍵字,而後是做爲某個對象的屬性或方法存在的語句,如.prop,而後逗號這樣用於斷句用的符號。但即便這樣,還會留下像Math, String等全局變量,這時咱們就經過vm取hasOwnerProperty進行排除。函數
下面就是經過新的parser轉換獲得的求值函數。性能
function anonymous(vm1372575919386) { var firstName = vm1372575919386.firstName return firstName } function anonymous(vm1372575919386) { var test1= vm1372575919386.test1, test2 = vm1372575919386.test2 return test1 && test2 }
而且進一步,咱們能夠在裏面塞進'use strict'來提升性能。雙向綁定
function anonymous(vm1372575919386) { 'use strict'; var firstName = vm1372575919386.firstName return firstName } function anonymous(vm1372575919386) { 'use strict'; var test1= vm1372575919386.test1, test2 = vm1372575919386.test2 return test1 && test2 }
如何存在過濾器
{{ new Date | date('dd MM yyyy') }}
function anonymous(vm1372896828095_0, filters1372896828095) { 'use strict'; var ret1372896828095 = new Date if (filters1372896828095.date) { try { ret1372896828095 = filters1372896828095.date(ret1372896828095, 'dd MM yyyy') } catch (e) { } } return ret1372896828095 }
憑藉着此新parser,avalon又有了一個質的提升。有關的parser的實現,能夠詳看該issue
讀者們也能夠對比angular的parser實現, avalon的是很是小巧的。
迷你MVVM框架在github的倉庫https://github.com/RubyLouvre/avalon
官網地址http://rubylouvre.github.io/mvvm/
你們能夠加入QQ羣:79641290進行討論,此羣爲技術羣,禁水!