再談JavaScript的closure--JavaScript 閉包

關於JavaScript的閉包,在個人博客上以前有一篇文章 https://www.cnblogs.com/wphl-27/p/8491327.htmlhtml

今天看了幾篇文章,感受又有了一些更深的理解,特記錄以下:閉包

其實關於JavaScript的閉包closure, 簡單點理解能夠以下:函數

 

在JavaScript中,一個函數A內部又包含一個函數B, 同時把內部函數B做爲函數A的返回值,這個時候,就造成了一個閉包。

咱們來看一個簡單的例子:
spa

 

var a = 5;

function TestAdd(){

   return a += 5;

}

TestAdd();    // a = 10
TestAdd();    // a = 15
TestAdd();    // a = 20
TestAdd();    // a = 25

 

上面的JavaScript腳本例子中,咱們定義了一個全局變量a, 在函數TestAdd中,對該全局變量a加5,因爲a是一個全局變量,因此每調用一次TestAdd方法,就會往a上累加5code

咱們的需求是: 若是須要更改a的值,則只能經過TestAdd這個方法來更改,不能經過其餘途徑來更改htm

可是,咱們看看上面的代碼,實現了咱們的需求嗎? 咱們確實能夠經過TestAdd方法來更改a的值,但同時因爲a是一個全局變量,咱們在其餘地方能夠很容易的修改它的值,好比 a = 34;  因此,這個代碼是達不到咱們需求的blog

如今咱們對它進行修改,咱們會很容易想到,既然需求是隻能經過方法TestAdd來修改a的值,那麼咱們能夠把變量a放到TestAdd內部去,代碼以下ip

function TestAdd(){

   var a = 5;
   return a += 5;

}

TestAdd();    // a = 10
TestAdd();    // a = 10
TestAdd();    // a = 10
TestAdd();    // a = 10

可是這樣,咱們發現,咱們原本但願4次調用TestAdd方法後,輸出的是25。但實際上輸出的倒是10. 由於如今a是函數TestAdd內部的局部變量,因此你每次調用TestAdd方法時,都會從新初始化a爲5博客

那麼咱們能如何解決這個問題呢,答案就是JavaScript Closure -- JavaScript 閉包, 代碼以下io

 

var Testadd = (function(){

   var a = 5;
   return function(){

      return a += 5;
    }
})();

TestAdd();    // a = 10
TestAdd();    // a = 15
TestAdd();    // a = 20
TestAdd();    // a = 25

上面的TestAdd是自執行函數,固然咱們也能夠寫成以下這樣

function myFunc(){

   var a = 5;
   return function(){

      return a += 5;
    }
}

var TestAdd = myFunc();

TestAdd();    // a = 10
TestAdd();    // a = 15
TestAdd();    // a = 20
TestAdd();    // a = 25

能夠看出,上面兩種寫法,TestAdd表明的都是內部返回的函數(閉包函數)function(){return a += 5;}  而它用到的這個變量a則是它的外部函數的變量,在咱們4次調用TestAdd()函數的過程當中,咱們都是在調用內部的函數。這個時候,雖然外部函數已經運行結束了,但外部函數的變量a卻被內部函數(閉包)引用,因此a並無被銷燬,而是被保存了起來,而且能夠經過閉包繼續操做。固然,外界沒法訪問a,它成了內部函數(閉包)的「私有變量」/

也就是說 內部函數會close-over(遮蔽,封蓋)外部函數的變量,直到內部函數所有調用完畢。

 

這裏特別要注意,你不能寫成這樣:

 

var Testadd = function(){

   var a = 5;
   return function(){

      return a += 5;
    }
};

TestAdd();    // function(){return a += 5 ;}
TestAdd();    // function(){return a += 5 ;}
TestAdd();    // function(){return a += 5 ;}
TestAdd();    // function(){return a += 5 ;}
相關文章
相關標籤/搜索