TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2011年5月23日 星期一

JavaScript function binding: arguments only

既然 JavaScript 1.8.5 已經有 bind 可以用, 為什麼不用它呢? 因為它有一個小問題, 就是它非得 bind 一個 instance 給 this, 但很多時候你是不想動到原本 this 所指向的 instance, 比方說某些 library 會要求 event handler 的 this 必須要指向某個 DOM Element. 於是當你只想 bind arguments 時, 這個無法忽略的第一個參數實在很惱人, 我自己試過丟 undefined 或 null 進去, 但結果 this 都被 bind 到 window 上. 幸好這個要求在 JavaScript 並不難實作, 我就自己刻了一個.
function bind( fn ) {
    var args = Array.prototype.slice.call( arguments, 1 );
    return function() {
        fn.apply( this, args.concat( Array.prototype.slice.call( arguments ) ) );
    };
}
Array.prototype.slice.call( arguments ) 算是慣用手法了, 直接把所有的函式引數轉成陣列. 第一個 args 的宣告是必要的, 因為 argurments 一旦進入其他 function 就會隨著 context 一起被置換掉.
裡面那層的 arguments 則是為了串接其他沒被 bind 的額外參數, 這點用範例比較能看出功用.
function add( a, b ) {
    return a + b;
}
// tmp( b ) === add( 1, b )
var tmp = bind( add, 1 );
// alert 3
tmp( 2 );
如果沒有把 anonymouse function 的 arguments 也接上去, 那麼 b 在 bind 之後就會是 undefined.

沒有留言:

張貼留言