作者fillano (冒牌費大公)
看板Ajax
標題Re: [問題][js] closure 和 prototype的差別~
時間Wed Jun 3 17:11:39 2009
closure簡單說就是function defined in function
用不用closure對於用this指定的property是沒差,但是對於區域變數就會有差別:
function test() {
var x=2;
var y=3;
this.getTest = function() {
return x*y;
}
}
var a = new test();
alert(a.getTest());
正常
而下面這樣的話:
function test() {
var x=2;
var y=3;
}
test.prototype.getTest = function() {
return x*y;
}
var a = new test();
alert(a.getTest());
就會出現錯誤。
其實用prototype或是closure沒差啦,出問題的是微軟...
微軟的瀏覽器跟javascript引擎是獨立的東西,導致使用closure的時候,參考到dom
物件無法被正常釋放,這是IE6的問題,新版的IE已經不會有問題了,所以可以放心用
closure。
有興趣的話可以看一下:
http://javascript.crockford.com/memory/leak.html
另外,上面提到的問題是,即使瀏覽器關掉記憶體也不會被釋放,而使用closure的時候
,其實會在特定狀況下,讓內部的function維持到函數執行結束還有用,這樣它所參考
到的本地變數也不會被釋放:
function test() {
var x=3;
var y=2;
return function() {
return x*y;
}
}
var a = test();
alert(a());
像上述情況,執行test()完畢後,它會把一個內部函數的參考傳給變數a,只要a還有效,
變數x跟y就必須留在記憶體中,否則無法正確執行。這可能會是一個無意間造成的記憶體
未釋放問題。更常見的是處理dom:
function addclick(node) {
node.onclick = function() {
alert(node.id);
}
}
addclick(document.getElementById("id"));
透過函數參數傳進來的變數,跟本地變數一樣意思。
以上是使用closure會有的問題,但是如果不是微軟的話,其實不嚴重,而且這是
javascript本身具備的特性。
--
Sapere Aude! 這就是啟蒙運動的口號!
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 60.250.95.16
1F:推 kevintwo:謝謝這位大大^^a 06/04 00:03
2F:→ kevintwo:請問最後一段的addclick 不是很懂問題所在? 06/04 00:05
3F:推 gpmm:拜謝指教 orz 06/04 00:47
4F:→ fillano:最後一段,node的事件處理函數在closure裡面用到node變數 06/04 08:44
5F:→ fillano:,這樣會讓這個變數參考到的node在addclick函數執行完以後 06/04 08:45
6F:→ fillano:也不會釋放。這也是剛剛提到IE6早期出現問題的主因。如果 06/04 08:46
7F:→ fillano:要釋放,只要另外把node的事件處理函數改掉就可以,但是IE 06/04 08:46
8F:→ fillano:6即使這樣,包括關掉瀏覽器,記憶體也不會釋放。 06/04 08:47
9F:→ fillano:現在的瀏覽器不會有這類的問題了,而且closure很好用,在 06/04 08:49
10F:→ fillano:你知道他的運作方式下,倒是不妨使用。 06/04 08:49
11F:推 kevintwo:瞭解了~~~ 謝謝說明~ 06/04 09:29