練習
wikipedia對閉包的說明…
閉包可以用來在一個函式與一組「私有」變數之間建立關聯關係。在給定函式被多次呼叫的過程中,這些私有變數能夠保持其永續性。變數的作用域僅限於包含它們的函式,因此無法從其它程式碼部分進行存取。…閉包可以用來完成資訊隱藏,並進而應用於需要狀態表達的某些程式設計範式中。
因為在這個例子中閉包已經超出了建立它的函式的範圍,所以變數…返回後繼續存在。在沒有閉包的語言中,變數的生命周期只限於建立它的環境。但在有閉包的語言中,只要有一個閉包參照了這個變數,它就會一直存在。
message='message from top!';
function wait(message) {
setTimeout(
//message變數超出建立的函式範圍, 會自動往上找, 在wait函式有宣告message, 在wait裡會一直存在
function timer() {console.log('insideLog:'+message);},
1000);
}
wait('message for closure!');
console.log('outsideLog:'+message); //message是抓到第一行宣告的全域變數(window.message)
//結果:
"outsideLog:message from top!"
"insideLog:message for closure!"
for (var i = 0; i <= 2; i++) {
setTimeout(function(){console.log(i);}, 1000*i);
}
//結果:3,3,3
//var宣告是全域, 不是區塊內私有變數
for (let i = 0; i <= 2; i++) {
setTimeout(function(){console.log(i);}, 1000*i);
}
//結果:0,1,2
//let為區塊變數, 每次執行會重新宣告, 跳出區塊就不存在
利用closure特性, 達到private及public的效果
function OrderModule() {
let orders = 0;
var copyRecipe = '';
function getOrder() {
console.log(orders);
}
function addOrder() {
orders++;
}
return {
getCurrentOrder: getOrder,
addOrder: addOrder
};
}
var foo = OrderModule();
foo.addOrder();
foo.addOrder();
foo.getCurrentOrder();
console.log(orders);
//結果:
/*
2
"Uncaught ReferenceError: orders is not defined"
*/