ホームページ  >  記事  >  ウェブフロントエンド  >  関数を返す JavaScript のカリー化関数_JavaScript のヒント

関数を返す JavaScript のカリー化関数_JavaScript のヒント

WBOY
WBOYオリジナル
2016-05-16 18:42:001330ブラウズ

初期のカリー関数は少し多態性がありました。つまり、分岐は関数パラメーターに基づいて内部的に選択されました。

コードをコピー コードは次のとおりです。以下の通り:

//http://www.openlaszlo.org/pipermail/laszlo-user/2005-March/000350.html
// ★★2005 年 3 月 8 日、 00:06、Steve Albin は次のように書きました:

function add(a, b) {

if (arguments.length < 1) {

return add;
} else if (arguments.length < 2) {

return function(c) { return a c }

} else {

return a b; >
}

}



var myadd = add( 2 );

var total = myadd(3); 🎜>

日本の先駆者は、Array のネイティブ関数を使用して引数を配列に変換できることを理解する前に、非常に複雑な正則化と eval を使用して、現代のカリー化の意味に近い関数を考え出したかもしれません。方法。




コードをコピーしますif (typeof fun != 'function') {

throw new Error("引数は関数である必要があります。");

if ( fun.arity == 0) {

throw new Error("関数には複数の引数が必要です。")

}

var funText = fun.toString ();

var args = /function .*((.*))(.*)/.exec(funText)[1].split(', '); 🎜>var firstArg = args.shift();

varrestArgs = args.join(', ');

var body = funText.replace(/function .*(.*) /, " ");

var curriedText =

"function (" firstArg ") {"

"return function ("restArgs ")" body

" }"

eval("var curried =" curriedText);

return
}




関数カレー(楽しい) { if (typeof fun != '関数') { throw new Error("引数は関数である必要があります。"); } if (fun.arity == 0) { throw new Error("関数には複数の引数が必要です。"); } var funText = fun.toString(); var args = /function .*((.*))(.*)/.exec(funText)[1].split(', '); var firstArg = args.shift(); varrestArgs = args.join(', '); var body = funText.replace(/function .*(.*) /, ""); var curriedText = "function (" firstArg ") {" 「戻り関数("restArgs")」本体 "}"; eval("var curried =" curriedText); カレーを返します。 } 関数 sum(x, y) { x y を返します。 } 関数 means3(a, b, c) { (a b c)/3 を返します。 } var a = カレー(合計)(10)(15) アラート(a)//25 var b = カレー(平均3)(10)(20, 30); アラート(b)//20 var c = カレー(カレー(合計))(10)()(20); アラート(c); var d = カレー(カレー(平均3)(10))(20)(30); 警告(d);



[Ctrl A すべて選択 注:
外部 Js を導入する必要がある場合は、
を実行するために更新する必要があります]その後クロージャの人気、そして配列変換引数の技術の発見により、現代のカリー化関数がついに登場しました。ちょうど 15 世紀から 17 世紀の大航海時代の地理的発見と同じように、JavaScript の世界が突然開かれました。たくさん。
コードをコピー

コードは次のとおりです:
//シンプルでモダンなカリー化関数関数カレー (fn, スコープ) { var スコープ = スコープ || var args = []; for (var i=2, len = argument.length; i args.push(arguments[i]);
return function() {
fn.apply(scope, args);


一般的なカリー化関数には 2 つの関数しかありません。実行状況は次のようになります。1 回目の実行ではパラメータが不足しており、内部関数に戻り、2 回目の実行で最終的に完了します。ただし、このパラメータに関するいくつかの記事はまだ作成できます。次の関数を見てください:




コードをコピー


コードは次のとおりです。

function sum( ){
var result=0;
for(var i=0, n=arguments.length; iresult = argument[i]; 結果を返します; } alert(sum(1,2,3,4,5)); // 15
いわゆるパラメーター不足の問題はありません。パラメーターを渡せば、それも計算されます。しかし、パラメーターが渡されない場合はどうなるでしょうか?そうですね、パラメータがあるかないかの違いです。パラメーターが存在する場合は、それ自体を継続的に実行させることができます。最後に、パラメーターなしで 1 回実行されます。つまり、前の手順はパラメータを保存するために使用されます。
var sum2=curry(sum);
sum2= sum2(1)(2)(3)(4)(5); // 15
一般的なものと比較関数のカリー化、これは少し難しいです。詳細についてはコメントを参照してください:

コードをコピー コードは次のとおりです:
varcurry= function(fn){ //元の関数のパラメータはfunctions
return function(args){//内部関数のパラメータはすぐに実行されるため、直接第3レベルに進みます//引数は第 3 レベルの内部に相対的です。関数はグローバル変数にすることができます。
var self= argument.callee;//それ自体を保存します (つまり、配列をパラメーターとして持つ 2 番目の関数)
return function(){ //これは 2 回目の呼び出しです Function
if(arguments.length){//さらにパラメータを追加する場合
[].push.apply(args,arguments);//適用現在渡されているすべてのパラメータを args
return self(args);
}else{
return fn.apply(this,args);//apply の 2 番目のパラメータは配列

}
}([ ])



; 関数 sum(){ var 結果 = 0; for(var i=0, n=arguments.length; i

関数 sum(){ var 結果 = 0; for(var i=0, n=arguments.length; i
<.>

コードをコピーします
コードは次のとおりです: 関数カレー(f) { if (f.length == 0) return f;
function iterate(args) {
if (args.length return f.apply (null, args);
return 関数 () {
return iterate(args.concat(Array.prototype.slice.call(arguments)))
}; iterate([]);
}



[Ctrl A すべて選択 注: 外部 Js を導入する必要がある場合は、 を実行するために更新する必要があります]
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。