淺析Javascript閉包的特性
Javascript閉包的定義非常晦澀——閉包,是指語法域位于某個特定的區域,具有持續參照(讀寫)位于該區域內自身范圍之外的執行域上的非持久型變量值能力的段落。這些外部執行域的非持久型變量神奇地保留它們在閉包最初定義(或創建)時的值(深連結)。
簡單來說,Javascript閉包就是在另一個作用域中保存了一份它從上一級函數或作用域取得的變量(鍵值對),而這些鍵值對是不會隨上一級函數的執行完成而銷毀。周愛民說得更清楚,閉包就是“屬性表”,閉包就是一個數據塊,閉包就是一個存放著“Name=Value”的對照表。就這么簡單。但是,必須強調,閉包是運行期概念,一個函數實例。
Javascript閉包的實現,通常是在函數內部再定義函數,讓該內部函數使用上一級函數的變量或全局變量。
ECMAScript認為使用全局變量是一個簡單的Javascript閉包實例。
- var sMessage = "Hello World";
- function sayHelloWorld(){
- alert(sMessage);
- };
- sayHelloWorld();
但它完成沒有體現Javascript閉包的特性……
現在比較讓人認同的Javascript閉包實現有如下三種
- with(obj){
- //這里是對象閉包
- }(function(){
- //函數閉包
- })()try{
- //...
- } catch(e) {
- //catch閉包 但IE里不行
- }
附上今天在無憂看到的問題:
要求:
讓這三個節點的Onclick事件都能正確的彈出相應的參數。
- <ul>
- <li id="a1">aa</li>
- <li id="a2">aa</li>
- <li id="a3">aa</li>
- </ul>
- <script type="text/javascript">
- <ul>
- <li id="a1">aa</li>
- <li id="a2">aa</li>
- <li id="a3">aa</li>
- </ul>
- <script type="text/javascript">
- for(var i=1; i < 4; i++){
- var id = document.getElementById("a" + i);
- id.onclick = function(){
- alert(i);//現在都是返回4
- }
- }
- </script>
客服果果的解答:
- for(var i=1; i < 4; i++){
- var id = document.getElementById("a" + i);
- /*
- 這里生成了一個匿名函數并賦值給對象 id_i;
- */
- id.onclick = function(){
- /*
- 這個i來源于局部變量,無法以window.i或者obj.i的形式在后期引用,
- 只好以指針或者變量地址方式保存在這個匿名函數中,
- 這就是傳說的閉包,所以所有這個過程中生成的事件句柄都使用引用
- 的方式來持久這個變量,也就是這些匿名函數共用一個變量i;
- */
- alert(i);
- };
- };
局部變全局
- for(var i=1; i < 4; i++){
- var id = document.getElementById("a" + i);
- id.i=i;//這個i有了根
- id.onclick=function(){
- alert(this.i)
- };
- };1.for(var i=1; i < 4; i++){
- var id = document.getElementById("a" + i);
- window[id.id]=i;//這個i有了根
- id.onclick=function(){
- alert(window[this.id]);
- };
- }
產生一對一的更多Javascript閉包
- for(var i=1; i < 4; i++){
- var id = document.getElementById("a" + i);
- id.onclick = new function(){
- var i2=i;//這個i是閉包的閉包
- return function(){
- alert(i2);
- }
- };
- }
【編輯推薦】