再看幾個Closure的小測試
Wed, 17 Dec 2008 23:11:28 +0800上一篇文章中,對於除了null以及undefined之外的型別做了一些測試,這幾天有用同樣的closure函數做一點深入的測試來試探他的效果。也很有趣。
主要的測試如下:
var changeObj = function(v) { v.a = "var ? attrib altered"; } var closureObj = function(v) { return function() { return v; } } var a = {a:"var a attrib a", b:"var a attrib b"}; var b = {a:"var b attrib a", b:"var b attrib b"}; var a1 = closureObj(a); var b1 = closureObj(b); a = null; b = null; alert(a1().a); alert(b1().a); changeObj(a1()); changeObj(b1()); alert(a1().a); alert(b1().a); closureObj = null; changeObj = null; alert(a1().a); alert(b1().a);
測試結果分別會跑出:
- var a attrib a
- var b attrib a
- var ? attrib altered
- var ? attrib altered
- var ? attrib altered
- var ? attrib altered
可以看到幾個效果:
- 每次呼叫closureObj產生的函數,都會各自保存各自的Context,即使closureObj函數沒作用了也一樣
- closureObj產生的函數返回的物件透過changeObj修改過就改變了下一次呼叫這個函數返回的物件
ECMA-262 Edition 3定義了一個Reference物件(下面稱作參考),所有的Assignment動作都要運作得像利用這個物件(實作上並不需要真正做出這個物件,只要表現得像有這個物件存在)。簡單地說,這個地方很像Java。
var a = {a:"var a attrib a", b:"var a attrib b"};
var a1 = closureObj(a);
a = null;
closureObj = null;
另外:
changeObj(a1());
基本上,這個部份用java的「參考」概念來概括,應該就差不多了吧?