over 3 years ago

Closure

能將外部函式的變數關到內部函式,用途是延續外部變數的生命

var Car = function(){
  var price = 1000;
  //閉包, 將price關在裡面

  function getPrice(){
    return price;
  };
  //閉包, 將price關在裡面

  function addPrice(p){
    price = price + p;
  };
  //回傳上述定義的closure function

  return {getPrice:getPrice,addPrice:addPrice};
};

var car = Car();
/*
此時Car()已經被執行完畢,並且回傳getPrice/addPrice給car  
所以price的生命週期已經結束了,但是我們透過closure把price關在裡面,延續了price的生命週期
*/
console.log(car.getPrice()); //print 1000

car.addPrice(1000);
console.log(car.getPrice()); //print 2000

有了閉包的概念後,我們接下來要了解,閉包所關起來的是變數的reference,而不是變數的value,這非常重要!

假設有個Array FA,我們預期FA[0]()會得到alert(0), FA[1]()會得到alert(1)

先看一個失敗的範例

var FA = [];//定義一個FA array

for(var i=0;i<5;i++){
    //將function指派給FA,透過閉包的方式將i關進去

    FA[i] = function(){
    alert(i);
  };
}  
FA[0]();//得到alert(5)

因為閉包是直接取用外部的變數reference而不是value,在for迴圈中結束後得到i=5,所以閉包中的i全部都是5

正確的範例

var FA = [];//定義一個FA array

for(var i=0;i<5;i++){
  //我們透過立刻執行函式的方式,將i在第一時間馬上綁入

    FA[i] = function(k){
    //透過return來回傳實際上要執行的函式

    return function(){
        alert(k);
    };   
  }(i);
}  
FA[0]();//得到alert(0)
← ReactJS Note (1) - Props and Data hooking Javascript 陣列vs物件 →
 
comments powered by Disqus