之前有讀到相關Closure的觀念,只不過平常實作是乎沒用到,因此並沒有太留意它的功用!
因此,在這邊將舉個JavaScript簡單的例子來了解一下它的獨到之處,以此記錄之!
一般來說,書上提到Closure主要會舉到函數內還有定義一函數的例子,並且此外層函數內的
區域變數,可以在內部函數內還保留它的生命週期,也就是說假設外部函數執行完之後,有
一event呼叫到內部函數時,此時內部函數內該變數值(外部函數宣告的)將是跑完外部函數時
最後記錄的結果!
好像有點抽像,因此實作一簡單的範例,如下:
第一部分只是動態的在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
外,內部函數可以直接使用外部函數宣告的變數來延續這持續性的結果!
因此,在這邊將舉個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
外,內部函數可以直接使用外部函數宣告的變數來延續這持續性的結果!
留言
張貼留言