iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
自我挑戰組

開始入坑網頁吧!系列 第 22

JavaScript 閉包(Closure) 下集

看這個程式碼,結果會是如何?

function ArrFunction(){
var arr=[];
for(var i=0;i<3;i++){
 arr.push(function(){
console.log(i);
});
}
return arr;
}
var fs=ArrFunction();

fs[0]();//3
fs[1]();//3
fs[2]();//3


也許你會驚訝,為甚麼不是0, 1, 2 呢?

這是因為ArrFunction在呼叫的時候,裡面的函數還沒有被呼叫,所以還不會console.log,
但是在執行ArrFunction時for loop 還是有在跑,等到 i 不小於3就跳出迴圈並return arr。
因此最後在記憶體的i是3。

而ArrFunction結束後,還記得昨天說的嗎?雖然它的執行環境已經結束了但是它的變數還是可以被內部的函數參考到,所以fs[0], fs[1], fs[2]參考到的i都是 3,彷彿是同一個父母的孩子們,要他們回答爸爸幾歲並不會因為生它們時的年齡不同而得到不同答案,因為它們都指向同一個記憶體位置。

如果想要得出 0, 1, 2 的結果呢?

function ArrFunction(){
var arr=[];
for(var i=0;i<3;i++){
let j=i;
 arr.push(function(){
console.log(j);
});
}
return arr;
}
var fs=ArrFunction();

fs[0]();//0
fs[1]();//1
fs[2]();//2


使用let 變數,如此裡面三個函數會指向不同的記憶體位置囉!!

另一個方法<使用立即函數>

function ArrFunction(){
var arr=[];
for(var i=0;i<3;i++){
arr.push(
(function(j){
console.log(j);
}(i))
);

}
return arr;
}

var fs=ArrFunction();
//0
//1
//2



上一篇
JavaScript 閉包(Closure) 上集
下一篇
JavaScript Callback(回呼)
系列文
開始入坑網頁吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言