JS筆記--探討閉包中內部函數在各情況下的可訪問範圍

         閉包是指有權訪問另一個函數作用域中的變量的函數,通過通過在一個函數中創建的另一個函數而獲得閉包。首先要說明的是,閉包並不等於匿名函數,匿名函數可以構成閉包,但不等於閉包。

         閉包的作用域,曾一直是困擾我多天的問題。爲什麼在某些情況下,閉包只能訪問到外部函數的活動對象?而在某些情況下,閉包能訪問到整個作用域鏈上的每一個變量?具體的問題,要歸結於閉包是否被引用。

         當某個函數被調用時,會創建一個執行環境及相應的作用域鏈。

1、當內部函數是在外部函數被調用的期間被調用的,則可以享受整個作用域鏈,並且得到的變量值都是即時的。

 

var k= 0;
functioncreateFunctions() {
 
    for (var i=0; i<10; i++) {
        (function() {
            alert(k);
            k++;
        }) (); //這裏需要給內部函數加個模仿塊級作用域處理,不然無法即時調用該函數。
        
    };
}
   
createFunctions();


 

以上JS代碼得到的結果是0~9。這說明了內部函數實時的調用了全局變量K並改變了它的值,同時能夠實時的得出結果。

 

2、內部函數並非在外部函數被調用時執行,而是在外部函數結束後才執行。換句話說,內部函數是被引用的,而非被直接調用的。這時,內部函數只能調用外部函數的活動對象(即外部函數各變量的最終值)。

 

function createFunctions(){
    var result =new Array();
 
    for (vari=0; i < 5; i++) {
        result[i] =function(){
             return i;
        };
/*在此,我們把函數賦值給數組result,並期待數組result返回i在每個時段的數值。但結果result的每一個值都是指向內部函數的指針。*/
 
    }
 
    returnresult;
}
    var funcs =createFunctions();
         /*在這裏funcs得到了數組result的賦值。在使用funcs數組時,因爲外部函數createFunctions已經結束了調用,因此只能留下自身的活動對象供以自身的內部函數調用。因此,funcs中的每一個值都是i的最終結果,即5*/
   
    for(var i=0;i < funcs.length; i++){
       document.write(funcs[i]() + "<br />");
    }


 

         在標註的部分,我們將內部函數賦值到result中。之後,在funcs中得到了函數的返回值result。實際上,funcs和result中全是對內部函數的指針。在使用funcs數組時,內部函數被調用(引用),然而createFunctions()早在創建funcs完畢後便結束調用,因此只留下自身本地活動對象給內部函數調用。此時的i爲5,所以funcs得到的結果也全部是5。

 

         因此,請務必區分在調用內部函數時,外部函數是否已經結束了調用。一般情況下,若內部函數是作賦值處理,在調用時外部函數一般已經結束調用,此時只能使用活動對象;若內部函數是作直接調用處理,則能夠使用作用域鏈中的每一個變量。

發佈了28 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章