iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
自我挑戰組

JavaScript老學徒筆記—馬步篇系列 第 31

IIFE立即執行函式

IIFE(Immediately Invoked Function Expression),是一種「可以立即執行的函式」。

一般的函式長這樣:

function doSomething (x){
	//do something
};

doSomething(參數);  //呼叫doSomething,執行程式區塊

而立即執行函式長成這個樣子:

(function doSomething (x) {
	//do something
})(參數);  //不用呼叫doSomething函式,X帶入參數,立即在程式區塊中執行

立即執行函式,不透過呼叫函式的方式,瀏覽器讀到函式後面附加的小括號( ),就知道要在函式宣告的當下立即執行。

假設洪七公嘴饞想吃叫化雞,叫黃蓉馬上烤一隻叫化雞來吃:

(function cooking(food){
	console.log(`丫頭去弄個${food}來吃吃!!!`);
})('叫化雞')  //丫頭去弄個叫化雞來吃吃!!!

cooking('東坡肉');  //Uncaught ReferenceError: cooking is not defined

如果在立即執行函式的外面再呼叫一次cooking函式,就會出現「Uncaught ReferenceError: cooking is not defined」。

既然提到了立即執行函式,讓我們利用它來解一下面試中常常會出現的考題:

「每次間隔一秒,依次印出0、1、2、3、4」

你會怎麼解呢?直覺應該利用for迴圈 + window.setTimeout()來解題:

for(var i = 0; i < 5; i++){
	window.setTimeout(function(){
		console.log(i);
	},1000)
}

結果是直接印出五個5,說好的0、1、2、3、4呢?

還記得前面提過「切分辨數最小範圍是function」,所以for迴圈和window.setTimeout()是個跑各的。

for迴圈是急驚風,而window.setTimeout()是慢郎中,window.setTimeout()剛剛過了一秒去捉外面的i來console.log()的時候,for迴圈已經跑完五次,i++變成5,不符合i<5的條件跳出迴圈了,所以window.setTimeout()捉迴圈的i,每次都捉到5。

那要怎麼解決這個問題呢? 我們可以把window.setTimeout()封裝在一個立即執行函式裡面,後面的小括號則帶入迴圈每次跑出來的 i,讓 i 把值帶入 x 裡面丟到 window.setTimeout() 去執行。

for(var i = 0; i < 5; i++){

	(function(x){
		window.setTimeout(function(){
			console.log(x);
		},x*1000);
	})(i);
}

這樣就會每隔1秒依序印出0、1、2、3、4了。

當然另外一個更簡單的解法則是把for迴圈的變數宣告「var i = 0」直接改成「let i = 0」,利用let是以大括號區塊為作用域的概念,讓for迴圈必須與window.setTimeout()一起跑。

for(let i = 0; i < 5; i++){
	window.setTimeout(function(){
		console.log(i);
	},1000)
}

這樣就會間格1秒,依序印出0、1、2、3、4了。


上一篇
回頭呼喊你的愛情:Callback回呼函式
下一篇
暗通款曲的閉包
系列文
JavaScript老學徒筆記—馬步篇35

尚未有邦友留言

立即登入留言