閉包的觀念,其實就和前幾天談到的作用域、變數宣告和作用域的觀念有關。只要有清楚知道其中差異,在理解閉包上就也能夠透過範例輕鬆理解了~。
我們主要是要認識作用域,理解變數所能夠被存取的範圍,所以範例中,我們要去注意變數money
money=1000
money - price
,而他能向外取用到 money = 1000
的值price=100
,執行 1000-100
function callMethod() {
var money = 1000;
return function (price) {
money = money - price;
return money;
}
}
let myMoney = callMethod()(100); // 存取內部函式的變數
console.log(myMoney);
為何要宣告變數 let myMoney = callMethod()(100);
若直接呼叫callMethod()
,都是回傳函式
所以透過宣告新的變數,將callMethod()
中的function存到變數 myMoney 中,並讓該變數可以執行。
function callMethod() {
var money = 1000;
changeMoney = function () {
money = 500;
}
return function (price) { // 這裡就是一個閉包,不過目前只會使用一次
money = money - price;
return money;
}
}
let updateMyMoney = callMethod(); // 存取內部函式的變數
console.log(updateMyMoney(100));
money - price
changeMoney()
之後,money = 500
,帶入參數後,也會從500去扣讓一個函式可以存取多個變數,並且能夠分別執行函式中的任務
MyMoney
YourMoney
,並傳入不同數值
function callMethod(newMoney) {
var money = newMoney || 1000;
return function (price) {
money = money - price;
return money;
}
}
let MyMoney = callMethod(500);
let YourMoney = callMethod(1000);
console.log(MyMoney(100));
console.log(YourMoney(100));
上述有提及因變數在全域環境的關係,所以在呼叫changeMoney時,要取得的值會被覆蓋。
在 ES6 透過 let 它可以幫我們把所定義的變數縮限在 block scoped 中,簡單說就是{}
來區隔。
自己的學習習慣,會透過影片課程中老師的解說,而自己邊做筆記、或是跟著範例進行操作,來加深自己的記憶,並透過反覆思索能夠更加理解內容。此外即便看過影片,也做完筆記,有時還會去搜尋 MDN 或是其他部落格文章,看看其他人用什麼角度來說明觀念。