回呼函式(callback function)

回呼函式:

所謂的回呼函式其實就是 " 將函式當作另一個函式的參數,由另外的函式來呼叫 "。

回呼函式其實十分常見,譬如在Javascript中監聽事件的添加,setTimeout 與 setInterval,或是陣列物件中的filter。

下面是一個添加監聽事件的例子:

當按下鍵盤按鍵時會取得鍵盤碼。

<script type="text/javascript">
document.addEventListener( 'keypress', getkey, false);
function getkey(event){
var myevent=event ? event:window.event;
alert(myevent.keyCode);
}
</script>

回呼函式的用途:

回呼函式可以用來維持函式的功能專一,能夠讓使用者廣泛的重複使用。同時還能夠讓使用者方便的擴展其功能,這在對一個函示庫撰寫是很重要的。而事實上許多函示庫也採用這樣的做法。

現在我想要用簡單的添加監聽事件來說明這理念。"監聽事件"本身就是一個功能專一的,而監聽事件後要進行什麼動作又是另外一件功能。因此把監聽事件,跟監聽事件後要做的動作分開來,這樣可以不用讓每個事件都是一個單獨的函式,還可以讓使用者決定哪個事件該作什麼。試想,如果將監聽與處理寫在同一函式,這勢必造成每個函式都必須不一樣,這種作法甚至連讓處理函式客製化都無法做到。

要有客製化的處理方式,最好的做法就是:回呼函式。

所以說如果你寫了一個函式,但裡面其實有2個甚至多個功能,或許可以嘗試用這方法,將他們拆開來,以維持函式的泛用。

回呼函式的陷阱:

1. 作用域的改變,看看下面這例子:

<script type="text/javascript">
//全域變數 x =10
var x=10;
var myobj1={
 x:5, //myobj1中的變數x=5
 getx:function(){ //取得 this.x
       return this.x;
      }
}
//定義一個回呼函式
function callbacktest(getx){
alert(getx());
}
//呼叫 callbacktest
callbacktest(myobj1.getx);
</script>

對話框出現的訊息是 10,而不是想像中的 5,這是因為函式的作用域改變了,因此他看到的this 指的是呼叫他的函式的所屬物件。而例子中的callbacktest是一個全域函式,因此this也指向了全域。

在使用 setTimeout 與 setInterval 時,其實也有相同的事情會發生。

2.回呼函式,或其傳回值。

回呼函式的寫法是 functionA (functionB),注意這一點,千萬不能寫成functionA (functionB()),這個意思便成了將函式B的傳回值傳遞給函式A,而不是將函式B本身傳遞給函式A。差別很大。

當然,Javascript中的函式其實可以是多型的。這可能造成函式A可以接受函式做為參數,也可以接受其他資料型態,譬如說JQuery的 .html。這種情況下要更小心,執行不會有問題,但結果卻可能不是你想要的結果,或是結果是你想要的,但卻不是正確的。

如果你想更了解其他函式觀念,可以參考看看下面這篇文章:函式 Function

我把許多函式的觀念與用法都收集在這篇文章內。

 
 

  按個讚!~支持本站!~

FB推薦載入中