Send en JavaScript-funksjon som parameter


Hvordan kan jeg sende en funksjon som en parameter uten at funksjonen kjører i «foreldre»-funksjonen eller bruker eval()? (Siden jeg har lest at det er usikkert.)

Jeg har dette:

addContact(entityId, refreshContactList());

Det fungerer, men problemet er at refreshContactList utløses når funksjonen kalles, i stedet for når den brukes i funksjonen.

Jeg kunne kommet rundt det ved å bruke eval(), men det er ikke beste praksis, ifølge det jeg har lest. Hvordan kan jeg sende en funksjon som en parameter i JavaScript?

Svar #1

Du trenger bare å fjerne parentesene:

addContact(entityId, refreshContactList);

Dette sender da funksjonen videre uten å kjøre den først.

Her er et eksempel:

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

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

addContact(1, refreshContactList);

Svar #2

Hvis du vil sende en funksjon, bare referer til den med navn uten parentesene:

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

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

Men noen ganger kan du ønske å sende en funksjon med argumenter inkludert, men ikke få den kalt før callbacken blir utført. For å gjøre dette, når du kaller den, pakk den bare inn i en anonym funksjon, slik:

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

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

Hvis du foretrekker det, kan du også bruke apply-funksjonen og ha en tredje parameter som er et array av argumentene, slik:

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"]); 

Svar #3

Eksempel 1:

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

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

Eksempel 2:

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

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

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

se på dette

Svar #4

For å sende funksjonen som parameter, fjern bare parentesene!

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); 

Tanken bak dette er at en funksjon er ganske lik en variabel. I stedet for å skrive

function ToBeCalled() { /* something */ }

du kan like godt skrive

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

Det er små forskjeller mellom de to, men uansett - begge er gyldige måter å definere en funksjon på. Nå, hvis du definerer en funksjon og eksplisitt tilordner den til en variabel, virker det ganske logisk at du kan sende den som parameter til en annen funksjon, og du trenger ikke parenteser:

anotherFunction(ToBeCalledVariable);

Svar #5

Det finnes et uttrykk blant JavaScript-programmerere: "Eval er ondskap", så prøv å unngå det for enhver pris!

I tillegg til Steve Fentons svar, kan du også sende funksjoner direkte.

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

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

Svar #6

Jeg klippet av alt håret mitt med det problemet. Jeg klarte ikke få eksemplene ovenfor til å fungere, så jeg endte slik :

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')");

Og det fungerer som en sjarm ... i det minste for det jeg trengte. Håper det kan hjelpe litt.

Relaterte artikler