個人總結:
臟檢查的全名是 臟數據檢查。是AngularJS命名的。
臟數據也就是產生了變化的數據。
臟檢查因一個原因而被稱為臟。它定時檢查而不是直接監聽屬性變化。我們把這個檢查稱為摘要周期(digest)。
angularJS監測對象變化不是像vue.js那樣通過Object.defineproperty這種接口,而是在某些情況下制定策略,通過復制保存一份數據,進行快照對比,來監測變化。
臟檢查這個東西,其實在三大主流前端框架中或多或少都有涉及。React 每次生成新的 Virtual DOM
,與舊 Virtual DOM
的 diff 操作本來就可以看做一次臟檢查。Vue 從相對徹底的拋棄了臟檢查機制,使用 Property
主動觸發 UI 更新,但是 Vue 仍然不能拋棄 track by
(用來標記數組元素的key) 這個東西。
通過將新舊數組的 track by
元素做 diff 猜測用戶的行為,最大可能的減少 DOM 樹的操作,這就是 track by
的用處。
Angular 1的性能被廣為詬病,因為在 Angular 1 的機制下,臟檢查的執行范圍過大以及頻率太過頻繁了。
資料一:
AngularJS remembers the value and compares it to a previous value. This is basic dirty-checking. If there is a change in value, then it fires the change event.
資料二:
Angular defines a concept of a so called digest cycle. This cycle can be considered as a loop, during which Angular checks if there are any changes to all the variables watched by all the $scopes. So if you have $scope.myVar defined in your controller and this variable was marked for being watched, then you are explicitly telling Angular to monitor the changes on myVar in each iteration of the loop.
資料三:
資料四:
angular中變量是雙向綁定的 ,那么怎么知道一個變量是否是變化了呢?
ng1: 是把所有事件都進行了包裝,例如把setTimeout包裝成$timeout,當這些事件觸發后會調用$apply, $apply 會從根也就是$rootScope, $rootScope.$digest()方法會遞歸把所有的子scope里面的watcher的新舊值來對比(臟檢測),如有變動,才會更新那個指令的模板渲染。在ng1版本里面 組件是指令的語法糖,渲染更新也是以指令為單位。
vue: 是在模板渲染的時候,會讀取{{}}之中的變量,觸發get。把 Dep.target也就是渲染watcher,放在了自己的依賴(Dep實例),dep.subs 數組中。
當哪個數據變化了 就會喊一聲(notify),他的訂閱者們(subs數組中的warcher們)就會更新( watcher.update() ) , 更新是以組件為單位。
我的總結:
假設教室玻璃碎了,ng1是 老師對學生們進行一一排查( 臟檢測 ),看看是誰。vue是學生主動站出來,是我,因為我的手破了,啊!(notify)好疼!