首頁 > web前端 > js教程 > 主體

JavaScript閉包函數存取外部變數的方法_javascript技巧

WBOY
發布: 2016-05-16 16:38:27
原創
2015 人瀏覽過

閉包是指有權存取另一個函數作用域中的變數的函數,但作用域的配置機制有一個需要注意的地方,即閉包只能取得包含函數中任何變數的最後一個值。

如以下案例:

function create(){
    var arr = new Array();  
 
    for (var i=0; i<10; i++){
        arr[i] = function(){
            return i;
        };  
    }
 
    return arr;
}
 
var c_arr = create();
 
for(var i=0; i<c_arr.length;i++){
    document.write("c_arr["+i+"] = "+c_arr[i]()+"<br />");    
}
登入後複製

執行結果:

JavaScript閉包函數存取外部變數的方法_javascript技巧

表面上看,似乎每個函數回傳的i值都不相同,例如c_arr[0]的值應該是0,c_arr[1]的值應該是1,以此類推。可結果每個函數都傳回10。為什麼呢?

因為每個函數的作用域鏈中都保存著create()函數的活動對象,所以它們所引用的都是同一個變數i。當for迴圈結束以後,i的值也變成10了,此時每個函數都引用保存變數i的同一個變數物件。

 

我們可以透過建立另一個網域函數來強制讓閉包的行為符合預期,使每個位置對應對應的值。

function create(){
    var arr = new Array();  
 
    for (var i=0; i<10; i++){
        arr[i] = function(num){
            return function(){
                return num; 
            };
        }(i);   
    }
 
    return arr;
}
 
var c_arr = create();
 
for(var i=0; i<c_arr.length;i++){
    document.write("c_arr["+i+"] = "+c_arr[i]()+"<br />");    
}
登入後複製

執行結果:

JavaScript閉包函數存取外部變數的方法_javascript技巧

定義了一個匿名函數,並立即執行匿名函數的機過賦給數組,這裡匿名函數有一個參數num,也就是最終的函數要回傳的值。在呼叫每個函數時我們傳入變數i。由於函數參數是按值傳遞的,所以就會將變數i的目前值賦值給參數num。而在這個匿名函數內部,又建立並回傳了一個訪問num的閉包,這樣一來arr數組中的每個函數都有自己num變數的一個副本,因此就可以傳回各自不同的數值了。

經典範例

我們再來看一個經典的例子,假設頁面有一組button標籤,我們利用腳本給這組button標籤綁定點擊事件,並且點擊時能彈出這是第幾個標籤。

<meta charset="utf-8" />
 
<button>第一个</button>
<button>第二个</button>
<button>第三个</button>
<button>第四个</button>
 
 
<script type="text/javascript">
 
var obj = document.getElementsByTagName('button');
for(var i=0;i<obj.length;i++){
    obj[i].onclick = function(){
        alert(i);
    };  
}
 
</script>
登入後複製

點選每一個按鈕結果

JavaScript閉包函數存取外部變數的方法_javascript技巧

表面上看,似乎點擊每個標籤應該會彈出不同數字

第一個應該彈出0;

第二個應該會彈出1;

以此類推。

可結果是所有按鈕都彈出4,顯然這不是我們想要的結果。

我們把程式改一下

<meta charset="utf-8" />
 
<button>第一个</button>
<button>第二个</button>
<button>第三个</button>
<button>第四个</button>
 
 
<script type="text/javascript">
 
var obj = document.getElementsByTagName('button');
for(var i=0;i<obj.length;i++){
    obj[i].onclick = function(num){
        return function(){
            alert(num);
        }       
    }(i);       
}
 
</script>
登入後複製

點第二個

JavaScript閉包函數存取外部變數的方法_javascript技巧

點選第四個

JavaScript閉包函數存取外部變數的方法_javascript技巧

我們只需要在函數內建立一個匿名函數,同上述案例同理。即可實現匿名函數捕捉外部變數i,結果每個按鈕彈的i值都不同。

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!