2016年6月13日 星期一

[筆記] 其實你早就在用closures了─談談closures和callback function


在看過前面幾篇關於closures的說明之後,不知道現在你是不是對於JavaScript中closures的概念有更清楚的概念和瞭解了呢?

如果還不清楚的話,可以先閱讀之前的文章喔!


在這篇文章中我們要來統整一下之前所學習到的概念,包括first class function、function expressions和closures,最後我們則會說明callback function的概念。

讓我們從一段程式例子看起


我們先寫一個名為SayHiLater的function,裡面會使用到setTimeout這個JavaScript中的內建函式,這個函式可以幫助我們延遲幾秒後才去執行另一個函式,裡面的3000,表示3000毫秒的意思,也就是3秒後幫我們執行裡面的那個function expression。(參考:setTimeout說明


執行的結果如下,會在執行這段程式後3秒鐘出現以下畫面:


在執行這段程式的過程中,你是否了解到你已經用到了我們之前所提的function expressionsclosures的概念了呢?

讓我們來重新看一下上面這段程式:


首先,在setTimeout裡面,我們在參數的地方建立了一個函式,這裡有兩個概念我們可以留意:第一,我們之所以可以直接把function當成參數代入setTimeout中,是因為在JavaScript中,function是屬於First Class Function,function就是一種物件,所以我們才可以直接把function放在參數中使用;第二,我們直接在參數的地方建立了一個參數,這是使用了Function Expression的特性,透過function expression建立了一個匿名函式。
接著來看看setTimeout,還記得我們之前談到JavaScript中asynchronous callback事件運作的方式,它會先把所有execution context中的內容執行完後,才去執行這個觸發事件。所以當所有的execution context執行完畢後,setTimeout會等待3000毫秒,接著JavaScript引擎會去監控是否有任何觸發事件要產生,這時候,它就找到了我們要執行的這個匿名函式。
當執行這個匿名函式的時候,會需要使用到參數name和greeting,從前幾個關於closures的筆記我們可以知道,雖然SayHiLater這個函式的execution context已經從JavaScript引擎中抽離了,但是name和greeting這兩個變數仍然存在其記憶體位置上,所以透過closures仍然可以指稱到這兩個變數。

所以從這個例子中,我們就已經應用到了先前所學的first class function, function expressions, event queue, 和closures這樣的概念。

那我常用的jQuery呢?


如果你有使用過jQuery的經驗,那你一定看過這樣的寫法:
/*jQuery 使用到first class function和function expression*/
$("#button-01").click(function(){

})
你在click的這個事件中又放了function( ){ },而這就是運用了first class function(把函式當成物件使用,因此才可以將函式代入參數的位置)和function expressions(直接在參數的位置寫入函式)的概念,另外,也使用了callback frunction的概念。

接著讓我們來看看callback function


什麼是callback function呢?
callback function指的是在一個function(例如,function A)中放入另一個function(例如,function B),而且當這個function A執行完後會觸發function B的執行。
讓我們看一個例子來了解callback function的概念。


在這裡我建立一個function名為CallBackYourName,同時代入參數callback。接著,在執行CallBackYourName的時候,我們在參數的地方代入function( ){ },這時候就構成了一個callback function。

因為我給原本的CallBackYourName這個函式另一個函式,而CallBackYourName這個函式在執行完畢後,又會把我給它的這個匿名函式加以執行,而這就是callback function的概念!

程式範例

function SayHiLater(name){
 
 var greeting = 'Hello, ';
 
 setTimeout(function(){

  console.log(greeting + name);

 }, 3000);
}

SayHiLater('PJCHEN');


/*callback function*/
function CallBackYourName(callback){
 var Greeting = 'Here is some work...';
 callback();
}

CallBackYourName(function(){
 console.log('My name is PJCHEN');
});

→回到此系列文章目錄

Share:

0 意見:

張貼留言