既然 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.
沒有留言:
張貼留言