工具人竟敢透露了一些身份的秘密。
我:打斷一下,所以為何你們三個工具人出現的瞬間,JS姐妹們就突然消失了?
方函式:喔~終於想起來了嗎?因為一直讓你接觸他們不是很好,所以我使用我的能力:閉包,把他們關起來了。
在了解閉包能力之前,你應該要先知道為何會需要閉包?
假設今天我們要計算一個值,但我們把初始值宣告在全域
let balance = 1000;
function caculatePrice(cost){
balance = balance - cost;
console.log(balance);
}
//花了100元
caculatePrice(100)
console.log(balance); //900
//再花100元
caculatePrice(100)
console.log(balance); //800
我們可以將它放入函式內,讓它成為區域變數,這樣就不會被大家共用
let balance = 1000;
//開銷計算
function caculateCost(cost){
balance = balance - cost;
return balance;
}
//花了100元
caculateCost(100)
console.log(balance,"第一次支出開銷"); //900
//再花100元
caculateCost(100)
console.log(balance,"第二次支出開銷"); //800
//書本開銷計算
function caclateCostOfBook(bookPrice){
balance = balance - bookPrice;
return balance;
};
caclateCostOfBook(200);
//然後我們再看一次我們的餘額
console.log(balance,"預期應該為800");
你會發現因為它們共用同一個變數值,所以不論我們執行caclateCostOfBook
或是caculateCost
時,都會影響balance
的值,進而造成計算結果不如預期。
怎麼辦呢?放入函式內
因為此時變數讀取有了所謂區域性,這樣就能避免儲存金額的變數,在全域被誤調值。
function caculatePrice(cost){
let balance = 1000;
balance = balance - cost;
console.log(balance);
}
//花了100元
caculatePrice(100)
console.log(balance); //900
//再花100元
caculatePrice(100)
console.log(balance); //800
但另一個問題出現了,不論你執行幾次caculatePrice
,都是從最初的金額$1000開始扣除,因為每次呼叫時,balance
都會被重新宣告。
這時候就是閉包(closure)上場的時刻!
先說筆者目前所知閉包最大的功能就是:私有化變數。
function caculatePrice(cost){
let balance = 1000;
return function (){
balance = balance - cost;
console.log(balance);
}
}
//將匿名函式存入變數
let x = caculatePrice(100);
x();//扣100
x();//再扣100
我們將caculatePrice(100)
存入變數x
這個動作,實際上你可以視為:將匿名函式存入變數x
。
x = function (){
balance = balance - cost;
console.log(balance);
}
但不同的是,這個匿名函式保留了對caculatePrice
字彙環境的參照,所以能透過 scope chain去讀取內部的值如:balance
,cost
,並且在每次執行時去影響數值。
方函式:若你把變數想像成姐妹
我:所以只有這三種區別?
-- to be continued --
那今天就到這邊摟!
每天的休息,是為了後面的追求,明天見。
你懂 JavaScript 嗎?#15 閉包(Closure)
所有的函式都是閉包:談 JS 中的作用域與 Closure
D10 - 點一籠熱呼呼的小籠閉包 Closure