Compose
Compose
把多個函式組合成一個函式,關係式如下。
程式範例
1 2 3 4 5 6 7 8 9 10 11
| var f = function(x){ return x + 1 ; } var g = function(x){ return x * 2 ; } f(g(1)); var F = compose(f,g); F(1);
|
實作
首先回傳一個函式,並利用閉包將傳入的函式紀錄起來。
1 2 3 4 5 6
| var compose = function(){ var fns = arguments ; return function(){ } }
|
這個回傳的函式要依次執行函式參數,注意要從最後一個開始執行。
這裡使用 call 而不直接呼叫是為了以防函式使用到 this 的情形。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| var compose = function(){ var fns = arguments ; return function(result){ for ( var i = fns.length - 1 ; i >= 0 ; i -- ){ result = fns[i].call(this,result) ; } return result ; } } var f = function(x){ return x + 1 ; } var g = function(x){ return x * 2 ; } f(g(1)); var F = compose(f,g); F(1);
|
可以使用reduce
,記得是從最後一個開始執行所以要使用 reduceRight
。
由於 reduce 用於陣列而 arguments 只是類陣列,所以先將 arguments 先轉為陣列。
1 2 3 4 5 6 7 8 9
| function compose() { var fns = Array.prototype.slice.call(arguments,0); return function (arg) { var result = fns.reduceRight(function(result , fn) { return fn.call(this,result); },arg); return result; }; };
|
Pipe
Pipe 其實和 Compose 很像,只是函式執行順序不一樣而已,因此改變程式順序即可。
1 2 3 4 5 6 7 8 9
| function pipe() { var fns = Array.prototype.slice.call(arguments,0); return function (arg) { var result = fns.reduce(function(result , fn) { return fn.call(this,result); },arg); return result; }; };
|
參考
Composing Functions in JavaScript