最近、私は JavaScript の関数プログラミングを学んでいます。そして、有名なカリー関数にとても興味があります。カリー関数は関数を受け取ることができ、とりあえずオリジナルの関数と呼ぶことにします。これは関数、カリー化された関数を返します。この関数は非常に強力で、実行プロセス中、元の関数の実行条件がトリガーされるまで、渡されたパラメーターを格納する関数を返し続けます。これはより一般的なので、説明するために例を示します:
元の関数:
var add = (x, y) => x + y
カリー化された関数:
var curryAdd = curry(add)
この追加には 2 つのパラメーターが必要ですが、curryAdd の実行では、渡されるパラメーターの数が少ない場合、より少ないパラメーターを渡すことができます。 add で必要なパラメータ以外の場合、add 関数は実行されません。curryAdd はパラメータを書き留め、別の関数を返します。この関数は、渡されたパラメータを引き続き実行できます。特別に、受信パラメータの状況を記録します。受信パラメータの合計数が add で必要なパラメータの合計数と等しい場合、元のパラメータの実行がアクティブになり、必要な結果が返されます。
// 此时只传入了一个参数 根据判断返回的是一个函数 var add2 = curryAdd(2) // add2 = function(...) {}
かなり良いですよね? さて、私たちの目標はこの魔法のカレー関数を書くことであり、それを 1 行で記述する必要があります。心配しないで、最初にその書き方を分析してから、段階的に最適化していきます。 。
上記の説明に基づいて、curry 関数に必要なものを見てみましょう。まず、関数には length という属性があることがわかります。それを保存するには、limit を使用します。
// 此时累计传入了两个参数 等于了add需要参数的总和 所以返回的是一个结果 // 相当于执行了add(2)(3) var result = add2(3) // result = 5
カレー関数は、実行する必要がある関数を返す必要があります。問題は、この関数の実行が元の関数の実行をアクティブにするかどうかを判断する必要があることです。渡されるパラメータ。関数または結果を返しますか?これは確かに問題です。渡されたパラメータが元の関数に必要なパラメータと等しい場合は、元の関数 fn
var curry = function(fn) { var limit = fn.length ... }
を実行する必要があります。パラメータは 2 つあります。1 つは渡されたパラメータの履歴を記録する必要があること、もう 1 つは返された関数が何をする必要があるかです
var curry = function(fn) { var limit = fn.length return function (...args) { if (args.length >= limit) { return fn.apply(null, args) } } }
ご存知のとおり、必要なのは、返された関数の実行パラメータを蓄積することだけです。渡されたパラメータを記録する この状況の目的のために、返す関数がしなければならないことは、上記のことを繰り返すことであり、これが関数の目的です。パラメータ args が行う必要があるため、名前が必要です。そうでないと実行できません。これを judgeCurry と呼びます
したがって、前述したように、関数を返すか、元の関数を実行します。
rreeeこの魔法のカレー関数をついに書き終えました。Compose と組み合わせると、本当に強力になります。
私たちの目標は、上記の関数を 1 行で書くことです。書き方?ちなみに、私はES6を使用しているので、かなりの時間を費やしました
var curry = function(fn) { var limit = fn.length return function (...args) { if (args.length >= limit) { return fn.apply(null, args) } else { return function(...args2) { } } } }
さて、何が問題なのか見てみましょう ちなみに、limitパラメータを使用しないようにするには、使用時に値を割り当てる必要があります。このように、
var curry = function(fn) { var limit = fn.length return function judgeCurry (...args) { if (args.length >= limit) { return fn.apply(null, args) } else { return function(...args2) { return judgeCurry.apply(null, args.concat(args2)) } } } }
はパラメータを判定する際に常にfn.lengthを評価する必要がありますが、fn.lengthの値は確定したくないのです。毎回ですが制限を使いたくないのですがどうすればよいですか?この関数をすぐに実行することを考えたに違いありません。 !
var currySingle = fn => judgeCurry = (...args) => args.length >= fn.length ? fn.apply(null, args) : (...args2) => judgeCurry.apply(null, args.concat(args2))
JavaScript の魔法にため息をつくしかありません。ついに、この魔法のカレーを一行で書き上げました。
上記は JavaScript 関数プログラミングでのカレー実装の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) をご覧ください。