underscore.jsのbindとカリー化
underscore.jsのbindについてのメモです。
underscore.jsのbind
第1引数の関数を実行する「関数」を返す
第1引数の関数内の「this」は第2引数の値が使われる
コメントにある通り、第3引数以降を渡すとカリー化ができます。
定義は以下の通りです。
// Create a function bound to a given object (assigning `this`, and arguments, // optionally). Binding with arguments is also known as `curry`. _.bind = function(func, obj) { var args = slice.call(arguments, 2); return function() { return func.apply(obj || {}, args.concat(slice.call(arguments))); }; };
公式ドキュメントに記載されている使用例です。
var func = function(greeting){ return greeting + ': ' + this.name }; func = _.bind(func, {name : 'moe'}, 'hi'); func(); => 'hi: moe'
上記使用例の場合どうなるかをコメントで示してみます
_.bind = function(func, obj) { // funcは function(greeting){ return greeting + ': ' + this.name }; // objは{name: 'moe'} var args = slice.call(arguments, 2); // ['hi'] return function() { // bind時に渡された引数'hi'と、実行時に渡された引数をconcatしたものを引数として、funcを呼び出す関数を返す return func.apply(obj || {}, args.concat(slice.call(arguments))); }; };
以下は、JavaScriptパターンで紹介されているカリー化の例です。
function schonfinkelize(fn) { var slice = Array.prototype.slice, stored_args = slice.call(arguments, 1); return function(){ var new_args = slice.call(arguments), args = stored_args.concat(new_args); return fn.apply(null, args); }; } function add(a, b, c, d, e){ return a + b + c + d + e } schonfinkelize(add, 1, 2, 3)(5, 5) // 16
underscore.jsのbindを使うと以下のように書けます
_.bind(add, null, 1, 2, 3)(5, 5) // 16
ちなみにカリー化をpythonでやるには、functoolsのpartialが使えます。
import functools def add(a, b, c, d, e): return a + b + c + d + e functools.partial(add, 1, 2, 3)(5, 5) # => 16
rubyではproc#curryメソッドが1.9から使えます。
add = lambda { |a,b,c,d,e| a+b+c+d+e } add.curry[1,2,3].call(5,5) # => 16
JavaScriptパターン ―優れたアプリケーションのための作法
- 作者: Stoyan Stefanov,豊福剛
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/02/16
- メディア: 大型本
- 購入: 22人 クリック: 907回
- この商品を含むブログ (77件) を見る