Passer une fonction JavaScript en paramètre

Comment passer une fonction comme paramètre sans que la fonction s'exécute dans la fonction" parent "ou en utilisant eval() ? (Depuis que j'ai lu que c'est l'insécurité.)

j'ai ceci:

addContact(entityId, refreshContactList());

cela fonctionne, mais le problème est que refreshContactList s'allume quand la fonction est appelée, plutôt que quand elle est utilisée dans la fonction.

je pourrais le contourner en utilisant eval() , mais ce n'est pas la meilleure pratique, selon ce que j'ai lu. Comment passer une fonction comme paramètre dans JavaScript?

516
demandé sur Nic Hartley 2012-11-08 13:34:04

13 réponses

vous avez juste besoin de supprimer la parenthèse:

addContact(entityId, refreshContactList);

passe ensuite la fonction sans l'exécuter en premier.

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);
740
répondu user75525 2012-11-08 09:43:33

si vous voulez passer une fonction, référez - la simplement 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 pourriez vouloir passer une fonction avec les arguments inclus , mais pas l'avoir appelée jusqu'à ce que le rappel soit invoqué. Pour ce faire, en l'appelant, il suffit de l'envelopper 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 appliquer et un troisième paramètre qui est un tableau d'arguments, comme tel:

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"]); 
231
répondu dallin 2014-11-07 01:23:03

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 ce

40
répondu Gadde 2017-05-23 12:02:49

pour passer la fonction en paramètre, il suffit de supprimer 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 derrière cela est qu'une fonction est tout à fait similaire à une variable. Au lieu d'écrire

function ToBeCalled() { /* something */ }

autant écrire

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

il y a des différences mineures entre les deux, mais de toute façon - les deux sont des façons valables de définir une fonction. Maintenant, si vous définissez une fonction et explicitement l'affecter à une variable, il semble tout à fait logique, que vous puissiez le passer comme paramètre à une autre fonction, et vous n'avez pas besoin de parenthèses:

anotherFunction(ToBeCalledVariable);
30
répondu naivists 2013-09-18 23:44:51

il y a une phrase chez 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
répondu series0ne 2012-11-08 09:39:35

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. J'étais également à la recherche de cette solution et j'ai essayé des solutions fournies dans d'autres réponses, mais j'ai finalement obtenu le travail de l'exemple ci-dessus.

5
répondu NullPointer 2014-01-23 11:29:16

je suggère de mettre les paramètres dans un tableau, puis de les diviser en utilisant la fonction .apply() . Donc 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
5
répondu Naramsim 2015-09-26 17:44:14

j'ai coupé tous mes cheveux avec cette question. Je n'ai pas pu faire fonctionner les exemples ci-dessus, donc 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 que j'ai besoin d'au moins. Espère que ça peut aider certains.

4
répondu Fenix Aoras 2016-04-15 09:31:35

Voici une autre approche:

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

a('Hello',function(e){alert(e+ ' world!');}); //=> Hello world     
2
répondu cochon 2014-01-15 16:21:22

en fait, semble un peu compliqué, n'est pas.

méthode get 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
répondu Hakkı Eser 2014-10-21 07:42:53

les autres réponses font un excellent travail de description de ce qui se passe, mais un" gotcha " important est de s'assurer que ce que vous traversez est en effet une référence à une fonction.

par exemple, si vous passez par une chaîne de caractères 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 "151970920

2
répondu Victor 2015-03-23 20:54:26

un certain temps quand vous avez besoin de traiter avec le gestionnaire d'événements si besoin de passer l'événement aussi comme argument , la plupart de la bibliothèque moderne comme react, angular pourrait avoir besoin de cela.

j'ai besoin de surcharger la fonction OnSubmit(fonction de la bibliothèque tierce partie) avec une validation personnalisée sur reactjs et j'ai passé la fonction et l'événement à la fois comme ci-dessous

ORIGINALLY

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

fait une nouvelle fonction upload et appelé passé onSubmit et l'é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
répondu sumit 2018-02-20 23:56:09

vous pouvez également utiliser un JSON pour stocker et envoyer des fonctions JS.

vérifier ce qui suit:

var myJSON = 
{
    "myFunc1" : function (){
        alert("a");
    }, 
    "myFunc2" : function (functionParameter){
        functionParameter();
    }
}



function main(){
    myJSON.myFunc2(myJSON.myFunc1);
}

ceci va imprimer "a".

ce qui suit a le même effet avec ce qui précède:

var myFunc1 = function (){
    alert('a');
}

var myFunc2 = function (functionParameter){
    functionParameter();
}

function main(){
    myFunc2(myFunc1);
}

qui a également le même effet avec ce qui suit:

function myFunc1(){
    alert('a');
}


function myFunc2 (functionParameter){
    functionParameter();
}

function main(){
    myFunc2(myFunc1);
}

Et un paradigme objet à l'aide de la Classe de l'objet à prototype:

function Class(){
    this.myFunc1 =  function(msg){
        alert(msg);
    }

    this.myFunc2 = function(callBackParameter){
        callBackParameter('message');
    }
}


function main(){    
    var myClass = new Class();  
    myClass.myFunc2(myClass.myFunc1);
}
-2
répondu gazgas 2013-05-09 08:18:01