閉包(Closure)的細節:共用與非共用變數
- 詳細內容
- 分類:Javascript
- 發佈:2013-07-01, 週一 22:02
- 點擊數:2346
閉包(Closure)的細節,共用與非共用變數:
一般函式在執行完畢時,內部的區域變數會被釋放掉,但如果在執行時產生了閉包。那閉包會保留其所在巢狀函式內的變數。讓他不至於被系統釋放掉。現在有一個問題是,閉包保留下來的變數,會與其他閉包共用嗎?這其實取決於閉包產生的位置與時間點。
如果在函式同一個呼叫期間建立了多個閉包,那這些閉包是共享該作用域變數的。若是不同的呼叫期間建立閉包,那閉包其實是處在不同的作用域,其變數自然就是不共用的。
同一個呼叫期間內的閉包共享變數:
<script type="text/javascript"> function closuretest(){ x=10; function changex(cx){ x=cx; } function showx(){ alert(x); } f1= changex; f2= showx; } closuretest(); f2();//顯示10 f1(5) f2();//顯示5 </script>
不同呼叫期間的閉包各自擁有變數:
<script type="text/javascript"> function closuretest(ox){ var x=ox; return function(){ alert(x); } } var f1=closuretest(5); var f2=closuretest(10); f1();//顯示5 f2();//顯示10 </script>
閉包的共用與非共用變數:
詭異的陷阱:
來自MDN的一個範例:
<p id="help">Helpful notes will appear here</p>
<p>E-mail: <input type="text" id="email" name="email"></p>
<p>Name: <input type="text" id="name" name="name"></p>
<p>Age: <input type="text" id="age" name="age"></p>
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}
function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
];
for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
}
}
setupHelp();
這程式可用來捕捉<input>標籤的focus事件,讓<input>標籤取得焦點時能夠在<p id="help">中顯示相關的說明,不過奇怪的是,不論焦點落在哪,說明總是會顯示"Your age (you must be over 16)"。為什麼會這樣?
其實就是閉包共享變數的原因,在函式內迴圈跑完時,變數item被設定為helpText[2],而閉包的函式主體:
function() { showHelp(item.help)};
其中的item是共享變數,已經被設定成為了helpText[2],因此不論焦點落在哪個<input>標籤,說明總是會顯示"Your age (you must be over 16)"。
解決這問題方法是使用更多的閉包。這裡就不在列出,請參考:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures
其他:
如果你想更了解其他閉包觀念,可以參考看看下面這篇文章:閉包(Closure)的基本概念。
我把許多閉包的觀念與用法都收集在這篇文章內。
按個讚!~支持本站!~
FB推薦載入中
你可能會有興趣的文章
- 閉包(Closure)的基本概念
- Function.prototype.call 呼叫函式
- Function.prototype.apply 呼叫函式
- Arguments 物件
- Function.arguments 函數參數