之前談過this與Closure,當時JS前輩Ammon提到了apply與call。今天在寫程式時剛好有機會用到,便順手整理了一下。

一般我們呼叫Function時,都會寫成funcName(arg1, arg2, ...)的形式。但像jQuery裡的事件函數,都用this來存取觸發事件的元素,若想由程式自行呼叫這些事件函數,就只能由元素去trigger()事件。傳統funcName()的呼叫方式,因無法指定this,顯然就無法滿足這種情境下的需求。

apply()call()是Function型別的兩個Method,apply()的語法是funcName.apply(thisArg, argsArray),第一個傳入的參數在就是函數中的this,而第二個參數則可傳一個參數陣列給該函數。call()與apply()用途相同,唯一的差別在於,call()必須一一明列出參數,例如funcName.call(thisArg, arg1, arg2, ...)。

底下是個例子,我寫了一個Button Click事件,其中用了this.value去取Button的顯示文字,並做一些後續的處理。範例裡只是個alert,但如果這些處理邏輯很複雜,我們想應用在Button Click以外的其他用途,依正統的程式架構設計,應將這段邏輯拆出來變成獨立函數,這樣子就可以被Button Click事件以及其他程式所共用。

但如果函數是執行期間動態指定的,或者你只是臨危受命加兩行程式救火(火燒屁股時還堅持做Refactoring應該會被蓋布袋),此時apply()就可以幫上大忙。在以下的例子裡,我假造了一顆"偽"按鈕,由於btnClick中只會用到this.value,我就宣告一個value屬性充數。就這樣,沒有Button也能享用Button Click事件囉!

<script type='text/javascript'>
$(function() {
function btnClick() {
    alert("Button[" + this.value + "] clicked!");
}
$("#a").click(btnClick);
var virtualButton = { value: "V" };
btnClick.apply(virtualButton);
});
</script>
</head><body>
<input type="button" value="A" id="a" />
</body>

Comments

# by Dave

解釋的非常清析,簡潔.

# by 遊子

一個字: 垃圾

# by 受益良多

那是兩個字

Post a comment