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

JavaScript閉包基礎

小云云
發布: 2018-02-23 11:39:27
原創
1242 人瀏覽過

什麼是閉包?本文主要和大家分享JavaScript閉包基礎,包括JavaScript閉包定義和用法,希望能幫助大家。

書上是這樣定義閉包的:

有權存取另一個函數作用域中變數的函數。

舉一個例子:

function test(){
    var a = 1;
    var b = function(){
        return a;   
    };
    return b;
}

var c = test();
console.log(c()); //1
登入後複製

這裡c是直接得到了b這個函數表達式,但是呼叫c之後可以得到test的局部變數a的值1,也就是c它存取到了test作用域中的變數。
其實我初學的時候一直不清楚閉包的意思,因為我感覺這種情況是理所當然的,噗,後來才知道原來就是說這個啊。

為什麼會產生閉包

究其根本,是因為b代表的函數包含test的作用域。
在某個函數被呼叫時會做下面這些事:

  1. 建立一個執行環境。

  2. 建立對應的作用域鏈(複製函數的[[Scope]]來完成)。

  3. 初始化函數的活動物件(arguments和其他命名參數),並被推入作用域最頂端。

而在作用域鏈中,外部函數的活動物件總是處於第二位,外部函數的外部函數的活動物件處於第三位...直到作為作用域鏈終點的全域執行環境。

舉個栗子

function test(value1,value2){
    if(value1 < value2)
        return -1;
    return 0;
}
var result = test(5,10);
登入後複製

以上首先定義了test函數,又在全域作用域中呼叫它。
第一次呼叫時,會建立一個包含this、arguments、value1和value2的活動物件。
全域執行環境的變數(this、result、test)則處於test執行環境作用域鏈中的第二位。
JavaScript閉包基礎
每個執行環境都有一個表示變數的對象,稱為變數物件。
全域環境的變數物件一直存在,test()函數局部環境的變數物件只有在執行的時候會存在。

函數的作用域鍊是保存在內部的[[Scope]]屬性中。
作用域本質是一個指標列表,只保存引用
以下是最初的栗子中test()的原型內容:
JavaScript閉包基礎
#匿名函數執行結束後,它的執行環境被銷毀了,但是傳回的活動物件沒有消失,所以閉包也不會消失,依舊存在記憶體中,如果給這個物件賦值null,就可以解除關係。

原來如此

讓我們瞅瞅這段熟悉的程式碼:

function test(){
    var result = new Array();
    for(var i=0;i<10;i++){
        result[i] = function(){
            return i;
        }
    }
    return result;
}
登入後複製

這個函數的實際結果是每個函數都回傳了10,因為它們實際的i都是同一個。
解決方法是用匿名函數:

function test(){
    var result = new Array();
    for(var i=0;i<10;i++){
        result[i] = function(num)(
            return function(){
                return num;
            }
        }(i);
    }
    return result;
}
登入後複製

由於中間多加上了一層,即每次把一個num值傳入,所以內部的函數是形成了各自num的閉包,於是就沒有像之前一樣共用了。

相關推薦:

javascript閉包var that=this詳解

深入理解javascript閉包

關於JavaScript閉包的小結



#

以上是JavaScript閉包基礎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板