在前端開發中,經常有這樣的naive的代碼,先是在HTML中定義了頁面結構:html
<div class="order-total">100</div>
在有交互時,用js經過其class來取到節點,而後將數據寫進去,如$('.order-total').html(300)
。前端
大約在三年前,這種作法在業界還頗爲流行,幾乎全部的書裏,網上教義,都在鼓吹這種分離JS和HTML的行爲,認爲這麼作就是天經地義。jquery
可是當代碼量多了以後,當頁面交互複雜了以後,咱們的代碼經常就成了:程序員
if (exist($('.selector'))) { // do something }
整個文件中,充斥着這樣或那樣的if
,由於沒人能肯定這個節點是否存在。還充斥着另外一種東西:編程
/* note: 這不是標準的jquery代碼 */ var quantity = $(this).parent().parent().find('.quantity-value');
這種連扔垃圾桶都不配的代碼真是寫的時候爽,後面維護者遭殃的典型範例,你必須不斷地切換js/html來審視其強依賴的結構。dom
那麼問題來了,爲何會寫出這樣的代碼呢?this
由於這種代碼是最符合直覺的書寫方式,一個初級程序員未經任何訓練,就能寫出這樣的代碼。它的名字叫:命令式編程。雙向綁定
命令式編程存在的問題就是,寫的人在寫的時候知道是怎麼回事,試圖掌控一切,後果是:
- 不知道代碼中的一系例選擇器對應着什麼節點
- 可維護性差,你不敢輕易改動類名或刪除節點,也不清楚節點的內容究竟對應着什麼數據
- 代碼量多code
上面說道,命令式編程試圖控制一切,而解決的辦法就是,交出控制權,將控制權反轉,即:htm
不要來找我,我會去找你。
原來的工做流:
order = 100
$('.order-div').html(order)
#JS主動來找DOM#若是頁面已經不須要這個信息了,將.order-div
從html中刪掉,重複上面的流程,執行到第三步時,JS將拋出異常,由於節點找不到。
控制反轉的工做流:
<div class='order-dv' ng-bind='order'></div>
,即#我會去找你#order = 100
innerHTML
將被自動設上100
若是頁面已經不須要這個信息了,將.order-div
從html中刪掉,重複上面的流程,對程序沒有任何影響,由於是節點本身去取數據,而不是JS主動去取節點,而這種方式就作:聲明式編程。
雙向綁定本質上是一種IoC的思想,經過讓:
達到了解耦合的目的。