web-dev-qa-db-fra.com

Comment puis-je passer une référence à une fonction, avec des paramètres?

Duplicate possible:
Comment puis-je prédéfinir des arguments dans un appel de fonction JavaScript? (Application de fonction partielle)

J'ai besoin de pouvoir passer une référence à une fonction avec un ensemble de paramètres donné .

Voici un exemple de passage d'une référence sans paramètres:

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

Maintenant, ce que je dois faire est de transmettre la même fonction f, mais cette fois, il me faudrait passer des paramètres à la référence. Maintenant, je peux le faire avec une fonction anonyme et appeler la fonction f avec des paramètres à l'intérieur de la fonction nouvellement créée, comme par exemple:

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

Mais ma question est, Y at-il un moyen de passer une référence directe à la fonction f avec des paramètres à fr, mais sans la renfermer dans une fonction anonyme ?

Que dois-je assigner à fr pour le rendre invocable sans paramètres (fr()), de sorte que f (1,2,3) est exécuté lorsque fr est invoqué?

[UPDATE] J'ai suivi la réponse de Jason Bunting à ici à propos de Fonction partielle et la fonction JavaScript qu'il publie correspond exactement à ce que je cherchais. Voici la solution:

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

Ce que vous cherchez est appelé application de fonction partielle .

Ne vous laissez pas berner par ceux qui ne comprennent pas la différence subtile entre cela et le currying, ils sont différents.

Une application de fonction partielle peut être utilisée pour implémenter, mais n'est pas currying. Voici une citation de un article de blog sur la différence :

Là où l'application partielle prend une fonction et crée une fonction qui prend moins d'arguments, Currying construit des fonctions qui prennent plusieurs arguments par composition de fonctions, chacune prenant un seul argument.

Ceci a déjà été répondu, voir la question pour votre réponse: Comment puis-je prédéfinir des arguments dans l'appel de fonction JavaScript?

Exemple:

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

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

Encore une fois, voir cette question pour les détails.

78
Jason Bunting

Vous pouvez également surcharger le prototype de fonction:

// 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__