web-dev-qa-db-fra.com

Passer une fonction JavaScript en paramètre

Comment passer une fonction en tant que paramètre sans que la fonction s'exécute dans la fonction "parent" ou utilise eval()? (Depuis que j'ai lu que ce n'est pas sûr.)

J'ai ceci:

addContact(entityId, refreshContactList());

Cela fonctionne, mais le problème est que refreshContactList se déclenche lorsque la fonction est appelée plutôt que lorsqu'elle est utilisée dans la fonction.

Je pourrais le contourner en utilisant eval(), mais ce n'est pas la meilleure pratique, d'après ce que j'ai lu. Comment puis-je passer une fonction en tant que paramètre en JavaScript?

601
imperium2335

Il vous suffit de supprimer la parenthèse:

addContact(entityId, refreshContactList);

Ceci passe ensuite la fonction sans l'exécuter au préalable.

Voici un exemple:

function addContact(id, refreshCallback) {
    refreshCallback();
    // You can also pass arguments if you need to
    // refreshCallback(id);
}

function refreshContactList() {
    alert('Hello World');
}

addContact(1, refreshContactList);
846
Fenton

Si vous voulez passer une fonction, il suffit de la référencer par son nom sans les parenthèses:

function foo(x) {
    alert(x);
}
function bar(func) {
    func("Hello World!");
}

//alerts "Hello World!"
bar(foo);

Mais parfois, vous voudrez peut-être passer une fonction avec les arguments inclus , sans l'avoir appelée jusqu'à ce que le rappel soit appelé. Pour ce faire, lorsque vous l'appelez, enveloppez-le simplement dans une fonction anonyme, comme ceci:

function foo(x) {
   alert(x);
}
function bar(func) {
   func();
}

//alerts "Hello World!" (from within bar AFTER being passed)
bar(function(){ foo("Hello World!") });

Si vous préférez, vous pouvez également utiliser la fonction apply et avoir un troisième paramètre qui est un tableau d'arguments, tel que:

function eat(food1, food2)
{
    alert("I like to eat " + food1 + " and " + food2 );
}
function myFunc(callback, args)
{
    //do stuff
    //...
    //execute callback when finished
    callback.apply(this, args);
}

//alerts "I like to eat pickles and peanut butter"
myFunc(eat, ["pickles", "peanut butter"]); 
282
dallin

Exemple 1:

funct("z", function (x) { return x; });

function funct(a, foo){
    foo(a) // this will return a
}

Exemple 2:

function foodemo(value){
    return 'hello '+value;
}

function funct(a, foo){
    alert(foo(a));
}

//call funct    
funct('world!',foodemo); //=> 'hello world!'

regardez ceci

50
Gadde

Pour passer la fonction en paramètre, supprimez simplement les crochets!

function ToBeCalled(){
  alert("I was called");
}

function iNeedParameter( paramFunc) {
   //it is a good idea to check if the parameter is actually not null
   //and that it is a function
   if (paramFunc && (typeof paramFunc == "function")) {
      paramFunc();   
   }
}

//this calls iNeedParameter and sends the other function to it
iNeedParameter(ToBeCalled); 

L'idée sous-jacente est qu'une fonction est assez similaire à une variable. Au lieu d'écrire

function ToBeCalled() { /* something */ }

vous pourriez aussi bien écrire

var ToBeCalledVariable = function () { /* something */ }

Il existe des différences mineures entre les deux, mais dans tous les cas, les deux sont des moyens valables de définir une fonction. Maintenant, si vous définissez une fonction et l'assignez explicitement à une variable, il semble assez logique que vous puissiez la passer en tant que paramètre à une autre fonction, et vous n'avez pas besoin de crochets:

anotherFunction(ToBeCalledVariable);
34
naivists

Il existe une phrase parmi les programmeurs JavaScript: "Eval is Evil", alors essayez de l'éviter à tout prix!

En plus de la réponse de Steve Fenton, vous pouvez également passer des fonctions directement.

function addContact(entity, refreshFn) {
    refreshFn();
}

function callAddContact() {
    addContact("entity", function() { DoThis(); });
}
15
series0ne

J'ai coupé tous mes cheveux avec ce problème. Je ne pouvais pas faire fonctionner les exemples ci-dessus, alors j'ai fini comme:

function foo(blabla){
    var func = new Function(blabla);
    func();
}
// to call it, I just pass the js function I wanted as a string in the new one...
foo("alert('test')");

Et ça marche comme un charme… pour ce dont j'avais besoin au moins. J'espère que cela pourrait aider certains.

6
Fenix Aoras

Je suggère de mettre les paramètres dans un tableau, puis de les séparer à l'aide de la fonction .apply(). Alors maintenant, nous pouvons facilement passer une fonction avec beaucoup de paramètres et l'exécuter d'une manière simple.

function addContact(parameters, refreshCallback) {
    refreshCallback.apply(this, parameters);
}

function refreshContactList(int, int, string) {
    alert(int + int);
    console.log(string);
}

addContact([1,2,"str"], refreshContactList); //parameters should be putted in an array
6
Naramsim

Vous pouvez également utiliser eval() pour faire la même chose.

//A function to call
function needToBeCalled(p1, p2)
{
    alert(p1+"="+p2);
}

//A function where needToBeCalled passed as an argument with necessary params
//Here params is comma separated string
function callAnotherFunction(aFunction, params)
{
    eval(aFunction + "("+params+")");
}

//A function Call
callAnotherFunction("needToBeCalled", "10,20");

C'est ça. Je recherchais également cette solution et ai essayé des solutions fournies dans d'autres réponses, mais j'ai finalement obtenu le résultat escompté.

6
NullPointer

Les autres réponses décrivent très bien ce qui se passe, mais il est important de savoir s’assurer que tout ce que vous passez est bien une référence à une fonction.

Par exemple, si vous passez à travers une chaîne au lieu d'une fonction, vous obtiendrez une erreur:

function function1(my_function_parameter){
    my_function_parameter();   
}

function function2(){
 alert('Hello world');   
}

function1(function2); //This will work

function1("function2"); //This breaks!

Voir JsFiddle

2
Victor

En fait, cela semble un peu compliqué, ne l’est pas.

obtenir la méthode en tant que paramètre:

 function JS_method(_callBack) { 

           _callBack("called");  

        }

Vous pouvez donner comme méthode de paramètre:

    JS_method(function (d) {
           //Finally this will work.
           alert(d)
    });
2
Hakkı Eser

Ici c'est une autre approche:

function a(first,second)    
{        
return (second)(first);           
}     

a('Hello',function(e){alert(e+ ' world!');}); //=> Hello world     
2
cochon

À un moment donné, lorsque vous aurez besoin de traiter avec le gestionnaire d’événements, vous aurez également besoin de passer événement comme argument, la plupart des bibliothèques modernes telles que react, angular pourraient en avoir besoin.

Je dois remplacer la fonction OnSubmit (fonction de la bibliothèque tierce) par une validation personnalisée sur reactjs et j'ai transmis la fonction et l'événement, comme ci-dessous.

À L'ORIGINE

    <button className="img-submit" type="button"  onClick=
 {onSubmit}>Upload Image</button>

FAIT UNE NOUVELLE FONCTION upload et appelé passé onSubmit et événement comme arguments

<button className="img-submit" type="button"  onClick={this.upload.bind(this,event,onSubmit)}>Upload Image</button>

upload(event,fn){
  //custom codes are done here
  fn(event);
}
0
sumit