[JavaScriptWeird]No.37 閉包與回呼

前言

整理完閉包與執行環境與一級函式後,我們確實地掌握到了這幾個名詞的基礎概念。但實際上如果曾經開發過 JavaScript ,在還不懂這些名詞的時候,或許已經無意間使用過這些技巧了,只是沒有意識到而已。像是如果使用過 setTimeout 或是 jQuery 事件,可能就使用過閉包。

閉包與回呼 (Closures And Callbacks)

像是 setTimeout 的小範例,使用了閉包與一級函式。

1
2
3
4
5
6
7
function sayHiLater(){  
var greet = 'Hello';
setTimeout(function(){
console.log(greet);
},3000)
}
sayHiLater();

setTimeout 接受兩個參數,一個是函式物件,一個為延遲執行時間。於是我們把一個匿名函式傳入,這是使用了 JavaScript 的一級函式觀念。

我們之前也討論過非同步過程、執行堆、 事件佇列的觀念,被包覆在 setTimeout 內的函式會先被放進事件佇列,等執行堆空了之後,才開始跑事件佇列裡的內容。

當開始運行 setTimeout 時,等到設定的時間過後便開始執行匿名函式,但 greet 不在函式裡,所以根據範圍鍊到外部環境尋找。

而雖然 sayHiLater 函式的執行環境已經不再執行堆內了,但是因為閉包,所以仍然可以取用 greet 變數。

像是 jQuery 的事件也使用到閉包與一級函式

1
2
3
4
// $('button').click(function(){

// });
// 因為沒有引用 jQuery 所以上面的程式無效,僅用來解說。

這段程式碼將一個匿名函式當成參數傳入 jQuery 中的 click 函式,使其在進行 click 動作時會觸發這個匿名函式。

jQuery 就是這樣使用函式表示式和一級函式概念的。

回呼 (callback)

當某個函式執行完畢,要給該函式執行的函式,稱為回呼。

也就是說,我呼叫函式 a ,然後給它函式 b ,當函式 a 執行完畢時,呼叫函式 b ,也就是說它回呼了 b 函式,這就是回呼函式。

1
2
3
4
5
6
7
8
9
10
11
12
13
function tellMeWhenDone(callback){  
var a = 1; // some work
var b = 1; // some work
callback();
}

tellMeWhenDone(function(){
console.log('做完了')
})

tellMeWhenDone(function(){
console.log('全都做完了')
})

以這個例子來說,我們建立了一個 tellMeWhenDone 的函式陳述句,並且可以帶入一個 callback 的參數。

接著呼叫 tellMeWhenDone 函式,並傳入一個匿名函式給它,再 tellMeWhenDone 函式執行到 callback() 時,會呼叫我們傳給它的匿名函式,因此輸出就如同我們預計的那樣。

0%