Backbone.js And JavaScript Garbage Collection
此文要說明的是在 Backbone.js 中並沒有特別去清理 Objects,它完全是交給 Developer 和 Browser 的 GC 來處理。首先說明 JavaScript 是 Garbage collected language,若 Object 沒有被 Reference 則能被回收,若有被 Reference 則不回收,所以要讓 JavaScript runtime 回收記憶體就要做 De-reference object 的動作。
De-reference 可以從 JavaScript 的 Variable 生命週期來看,分為 Global scope 和 Function scope(Local scope):
1. Global scope: 當某個 Variable 宣告在 Global scope 中,它會被 GC 回收的時機為,重新整理頁面、Load page completely from server、關閉瀏覽器或者是關閉分頁,當有觸發到以上所說的狀況時才會自動的被回收,否則 Variable 所指向的 Object 或 Value 會一直存在在記憶體中。
2. Function scope: 當 Variable 宣告在 Function 理,就是 Local variable,而釋放 Local variable 是在執行完 Function 離開後並且此 Function 沒有被 Reference 時,就能被 GC 回收。在這邊要注意的就是,通常沒有被回收就是還有被 Reference,這種狀況通常是用了 JavaScript 的某種技巧,能讓 Local 的東西活久一點,能達到此狀況大致上就如以下所示:
- Returned values from functions
- Closures
- Object attributes and methods
- Callback functions and DOM events
Return value:
我想此文所說的 Return value 的狀況大概就是像下面這樣的 Code:
function foo() {
// Function scope heare
var inner = 'Hello World!';
/* Do some thing stuff */
:
:
return inner;
}
// outer in global scope
var outer = foo();
依照上面的 Rule 來看,執行 foo 時 inner 會在離開 Function scope (就是離開 '}' ) 後,就被釋放囉! 但是它會將回傳值 Assign 到 outer,此時 outer 處於 Global scope,除非 outer 離開了 Global scope,否則它會存在於記憶體中。
Closures:
Closure 我想應該是很抽象的,Closure 為某個 Function 內有一個 Nested function 組成 Parent scope 和 Nested scope,Nested scope 可以去存取 Parent scope 的 Variables ,並且當 Function 執行後,有 Reference 指向 Nested function,大致上是這樣解釋,看不懂得可以參考此連結
Object attributes and methods:
Object attributes and methods 一樣是依照上述的 Rule ,此種狀況還蠻常見的
var obj;
obj.foo = thatObj;
此時只要 obj 的生命週期沒結束 thatObj 也不會結束,只要主動作 De-reference 的動作(在 Global scope 的狀況)例如:delete obj.foo; 或者是離開 Function scope 就會被回收了
Callback functions and DOM events:
在 JavaScript 中,非同步的狀況很常用到 Callbak function,例如:AJAX, setTimeout 或 setInterval,當 Callback 當作參數或者指派給某個 Object 後,此 Object 會 Reference 到 Callback function,若此 Object 為 Function scope object ,當離開 Function scope ,Callback function 就可以被回收,若為 Global scope object,一樣會依照上述的 Rule
在這裡比較特殊的是當 DOM object 的 Event 去 Reference 某個 Event handler( Callback ),我們必須去釋放 Dom reference 和 Event handler reference
作者最後有說明在 Backbone 中要如何去移除 Reference ,這就要看他另一篇文章了
以上大致上是我看完此篇文章的心得,不敢保證一定正確,有錯誤的話歡迎指證