JS – 閉包

JS – 閉包

閉包就是可以調用某一涵數內部的變數,或者也可以說父涵數內部有個子涵數,而子涵數可以使用父函數的變數。

但更精準來說,應該是當我們想保存一個變數不要馬上被銷毀,然後又不想要汙染全局變數時,就會形成 閉包 。這也是 閉包 主要作用,變數的延伸,以即不污染全局變數。如下面的例子:

function fn1(){
   let a = 10;
   function fn2(){
       a++;
       console.log("fn2========>",a)
   }
   return fn2;
}

let f= fn1(); 
f(); //11
f(); //12

上面這段程式碼,我們可以這樣解釋。fn1( )的結果給了一個全局變數 f,導致fn2( ) 和 a 變數一直存在記憶體中,沒有回收,所以 fn2( ) 返回結果,會存在於全局變數當中。由於 fn1( ) 返回的是一個函數,這個函數對於局部變數存在引用,就形成閉包。

用RPG 升級說閉包

我想如果用遊戲的例子來說明閉包或許就更容易理解了,我們在玩RPG遊戲時,例如我們有2個角色,分別為法師和騎士,在LV1 時,2隻角色初始HP都是100,然後每當等級提升時,角色的血量依據角色不同,血量增加也有所不同。程式碼如下:

function levelUp(){

     let baseHp = 100;
     let lv = 1;

     return function(name,hp){
          baseHp = baseHp + hp;
          lv ++ ;
          console.log(`【${name}】升級了!!等級為${lv},血量為====>${baseHp}`)
    }
}
// 法師
   let mage = levelUp();
   setInterval(()=>{
       mage("法師",10);
   },5000)

// 騎士
   let knight = levelUp();
   setInterval(()=>{
      knight("騎士",30);
   },2000)

因為法師升級較慢,所以5秒升1級,騎士2秒升1級。法師和騎士各自調用 levelUp ( ) 涵數,裡變的變數也屬於各自自己的,不會互相干擾影響,即使未來,在創一隻角色妖經,同樣可調用 evelUp ( ) 涵數也OK。


閉包使用場景

取2數之間值

如果有一陣列裡面元素分別為1~9,我們想取大於3小於8知間的數字我們可以這樣做,這樣也是一個必包的應用。

 let arr = [1,2,3,4,5,6,7,8,9];
 function getValue(a,b){
    let temp = [];
    temp = arr.filter((v)=>{
         return v > a && v < b
    })
    return temp;
 }

const result = getValue(3,8)