web-dev-qa-db-ja.com

パラメータを使用して関数への参照を渡すにはどうすればよいですか?

可能性のある複製:
JavaScript関数呼び出しで引数を事前設定するにはどうすればよいですか?(部分関数アプリケーション)

与えられたパラメーターのセットを持つ関数への参照を渡すことができる必要があります

参照を渡す例withoutparameters

_var f = function () {
    //Some logic here...
};

var fr = f; //Here I am passing a reference to function 'f', without parameters
fr(); //the 'f' function is invoked, without parameters
_

ここで必要なのは、同じf関数を渡すことですが、今回はパラメーターを参照に渡す必要があります。これで、匿名関数でそれを実行し、次のように、新しく作成された関数内のパラメーターでf関数を呼び出すことができます。

_var f = function () {
        //Some logic here...
    };

var fr = function (pars) {
    f(pars);
}; //Here I am creating an anonymous function, and invoking f inside it

fr({p : 'a parameter'}); //Invoking the fr function, that will later invoke the f function with parameters
_

しかし、私の質問は、fへのパラメーターを使用してfr関数への直接参照を渡す方法はありますが、匿名関数で囲むことはありませんか?

frに割り当てる必要があるのは、パラメータ(fr())なしで起動できるようにするためです。したがって、frが呼び出されますか?

[UPDATE]私は Jason Buntinghere について部分関数について彼がそこに投稿したJavaScript関数は、まさに私が探していたものです。解決策は次のとおりです。

_function partial(func /*, 0..n args */) {
  var args = Array.prototype.slice.call(arguments).splice(1);
  return function() {
    var allArguments = args.concat(Array.prototype.slice.call(arguments));
    return func.apply(this, allArguments);
  };
}
_
88
Andreas Grech

後は、部分関数アプリケーションと呼ばれます。

カレーとカレーの微妙な違いを理解していない人にだまされてはいけません。彼らは異なっています。

部分関数アプリケーションを使用して実装できますが、カリー化ではありません。以下は 違いに関するブログ投稿 からの引用です:

部分的なアプリケーションが関数を受け取り、それからより少ない引数を取る関数を構築する場合、カリー化は、それぞれが単一の引数を取る関数の構成によって複数の引数を取る関数を構築します。

これはすでに回答済みです。回答については、この質問を参照してください: JavaScript関数呼び出しで引数を事前設定するにはどうすればよいですか?

例:

var fr = partial(f, 1, 2, 3);

// now, when you invoke fr() it will invoke f(1,2,3)
fr();

繰り返しますが、詳細についてはその質問を参照してください。

78
Jason Bunting

Functionプロトタイプをオーバーロードすることもできます。

// partially applies the specified arguments to a function, returning a new function
Function.prototype.curry = function( ) {
    var func = this;
    var slice = Array.prototype.slice;
    var appliedArgs = slice.call( arguments, 0 );

    return function( ) {
        var leftoverArgs = slice.call( arguments, 0 );
        return func.apply( this, appliedArgs.concat( leftoverArgs ) );
    };
};

// can do other fancy things:

// flips the first two arguments of a function
Function.prototype.flip = function( ) {
    var func = this;
    return function( ) {
        var first = arguments[0];
        var second = arguments[1];
        var rest = Array.prototype.slice.call( arguments, 2 );
        var newArgs = [second, first].concat( rest );

        return func.apply( this, newArgs );
    };
};

/*
e.g.

var foo = function( a, b, c, d ) { console.log( a, b, c, d ); }
var iAmA = foo.curry( "I", "am", "a" );
iAmA( "Donkey" );
-> I am a Donkey

var bah = foo.flip( );
bah( 1, 2, 3, 4 );
-> 2 1 3 4
*/
2
SZ__