JavaScript - 閉包(Closure)的簡單應用

之前有讀到相關Closure的觀念,只不過平常實作是乎沒用到,因此並沒有太留意它的功用!

因此,在這邊將舉個JavaScript簡單的例子來了解一下它的獨到之處,以此記錄之!

一般來說,書上提到Closure主要會舉到函數內還有定義一函數的例子,並且此外層函數內的

區域變數,可以在內部函數內還保留它的生命週期,也就是說假設外部函數執行完之後,有

一event呼叫到內部函數時,此時內部函數內該變數值(外部函數宣告的)將是跑完外部函數時

最後記錄的結果!

好像有點抽像,因此實作一簡單的範例,如下:
window.onload = function(){
 //1.create a element link1 ~ link4
 var linkElm = ['link1','link2','link3','link4'];
 for(var i = 0 ; i < linkElm.length ; i ++){
  linkObj = document.createElement("a");
  
  linkObj.textContent = linkElm[i];
  
  linkHref = document.createAttribute("href");
  linkHref.value = "#";
  
  linkIndex = document.createAttribute("index");
  linkIndex.value = i;
  
  linkObj.setAttributeNode(linkHref);
  linkObj.setAttributeNode(linkIndex);
  
  document.body.appendChild(linkObj);
  document.body.innerHTML += "\n";
 }
 
 //2.define a element click event
 var links = document.getElementsByTagName('a');
 var records = [];
 for(var i = 0 ; i < links.length ; i ++){
  links[i].onclick = function(){
   n = this.getAttribute("index");
   records.push(links[n].text);
   console.log("點擊的歷史記錄:",records.join("=>"));
  }
 }
}

第一部分只是動態的在body內建立四個連結元素

第二部分為幫這四個連結定義click event,此時請注意,records array為外層的匿名函數所

宣告的,在這當下它是一空的陣列。定義的event很單純,就是當click時console.log(Chrome)

會印出該records內的點擊記錄,當點第一次時此時records為空,點第二次時此時records還保

有之前的紀錄,它的生命週期並沒有結束! 閉包產生了具有持續性的區域變數!

而i如果在內部函數內被alert的話,此時將會是4,如同上述提到的"此時內部函數內該變數值

(外部函數宣告的)將是跑完外部函數時最後記錄的結果!"。因此,您在內部函數內不可撰寫

links[i].text,因為links[4] => undefined



從這邊我可以想像的是,如果使用closure的概念,records是乎就不用宣告在window.onload

外,內部函數可以直接使用外部函數宣告的變數來延續這持續性的結果!

留言