89 votes

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

Duplicata possible :
Comment puis-je prédéfinir les arguments dans l'appel de fonction JavaScript ? (Application partielle de la fonction)

J'ai besoin de pouvoir passe une référence à une fonction avec un jeu 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 passer le même f mais cette fois, je devrais passer des paramètres à la référence. Maintenant, je peux le faire avec une fonction anonyme et invoquer la fonction f avec des paramètres à l'intérieur de la fonction nouvellement créée, comme ceci :

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, Existe-t-il un moyen de transmettre une référence directe à l'interface de l'utilisateur ? f Avec des paramètres à fr mais sans l'enfermer dans une fonction anonyme ?

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

[MISE À JOUR] J'ai suivi Jason Bunting La réponse de l'entreprise à ici sur le Fonction partielle et la fonction JavaScript qu'il y poste est exactement ce que je recherchais. 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);
  };
}

79voto

Jason Bunting Points 27534

Ce que vous recherchez s'appelle application partielle de la fonction .

Ne vous laissez pas tromper par ceux qui ne comprennent pas la différence subtile entre cela et le curry, ils sont différent.

L'application d'une fonction partielle peut être utilisée pour mettre en œuvre, mais n'est pas currying. Voici une citation de un billet de blog sur la différence :

Alors que l'application partielle prend une fonction et construit à partir de celle-ci une fonction qui prend moins d'arguments, le curage construit des fonctions qui prennent plusieurs arguments par composition de fonctions qui prennent chacune un seul argument.

La réponse à cette question a déjà été donnée, consultez cette question pour obtenir votre réponse : Comment puis-je prédéfinir les arguments dans un 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.

2voto

SZ__ Points 9

Vous pouvez également surcharger le prototype de la 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
*/

-4voto

lawnsea Points 2226

Ce qui suit est équivalent à votre deuxième bloc de code :

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

var fr = f;

fr(pars);

Si vous voulez réellement passer une référence à une fonction à une autre fonction, vous pouvez faire quelque chose comme ceci :

function fiz(x, y, z) {
    return x + y + z;
}

// elsewhere...

function foo(fn, p, q, r) {
    return function () {
        return fn(p, q, r);
    }
}

// finally...

f = foo(fiz, 1, 2, 3);
f(); // returns 6

Mais il est presque certain que vous feriez mieux d'utiliser un framework pour ce genre de choses.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X