Przekazać funkcję JavaScript jako parametr

Jak przekazać funkcję jako parametr bez funkcji wykonywanej w funkcji "rodzica" lub za pomocą eval()? (Odkąd przeczytałem, że jest niepewny.)

Mam to:

addContact(entityId, refreshContactList());

Działa, ale problem polega na tym, że refreshContactList uruchamia się, gdy funkcja jest wywołana, a nie gdy jest używana w funkcji.

Mógłbym obejść to używając eval(), ale to nie jest najlepsza praktyka, zgodnie z tym, co czytałem. Jak przekazać funkcję jako parametr w JavaScript?

Author: Nic Hartley, 2012-11-08

13 answers

Wystarczy usunąć nawias:

addContact(entityId, refreshContactList);

To przekazuje funkcję, nie wykonując jej wcześniej.

Oto przykład:

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
Author: user75525,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-08 09:43:33

Jeśli chcesz przekazać funkcję, po prostu odwołaj się do niej po nazwie bez nawiasów:

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

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

Ale czasami możesz chcieć przekazać funkcję z argumentami zawierającymi, ale nie wywoływać jej, dopóki nie zostanie wywołana funkcja zwrotna. Aby to zrobić, podczas wywoływania go, po prostu owinąć go w funkcję anonimową, w ten sposób:

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

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

Jeśli wolisz, możesz również użyć funkcji apply i mieć trzeci parametr, który jest tablicą argumentów, jak na przykład:

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
Author: dallin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-07 01:23:03

Przykład 1:

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

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

Przykład 2:

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

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

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

Spójrz na to

 40
Author: Gadde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:49

Aby przekazać funkcję jako parametr, po prostu usuń nawiasy!

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

Idea jest taka, że funkcja jest bardzo podobna do zmiennej. Zamiast pisać

function ToBeCalled() { /* something */ }

Równie dobrze możesz napisać

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

Istnieją niewielkie różnice między nimi, ale w każdym razie - oba są poprawnymi sposobami definiowania funkcji. Teraz, jeśli zdefiniujesz funkcję i jawnie przypisasz ją do zmiennej, wydaje się logiczne, że możesz przekazać ją jako parametr do innej funkcji, i nie potrzebujesz nawiasów:

anotherFunction(ToBeCalledVariable);
 30
Author: naivists,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-18 23:44:51

Wśród programistów JavaScript pojawia się zdanie: "Eval jest złem", więc staraj się tego unikać za wszelką cenę!

Oprócz odpowiedzi Steve ' a Fentona, można również przekazać funkcje bezpośrednio.

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

function callAddContact() {
    addContact("entity", function() { DoThis(); });
}
 15
Author: series0ne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-08 09:39:35

Możesz również użyć eval(), aby zrobić to samo.

//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");
To wszystko. Szukałem również tego rozwiązania i próbowałem rozwiązań podanych w innych odpowiedziach, ale w końcu dostałem to działanie z powyższego przykładu.
 5
Author: NullPointer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-23 11:29:16

Proponuję umieścić parametry w tablicy, a następnie podzielić je za pomocą funkcji .apply(). Więc teraz możemy łatwo przekazać funkcję o wielu parametrach i wykonać ją w prosty sposób.

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
Author: Naramsim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 17:44:14

Obcięłam sobie włosy tym problemem. Nie mogłem sprawić, by powyższe przykłady działały, więc zakończyłem tak:

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')");
I to działa jak urok ... przynajmniej na to, czego potrzebowałem. Mam nadzieję, że to może pomóc.
 4
Author: Fenix Aoras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-15 09:31:35

Oto inne podejście:

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

a('Hello',function(e){alert(e+ ' world!');}); //=> Hello world     
 2
Author: cochon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-15 16:21:22

W rzeczywistości, wydaje się trochę skomplikowane, nie jest.

Metoda Get jako parametr:

 function JS_method(_callBack) { 

           _callBack("called");  

        }

Możesz podać jako parametr metodę:

    JS_method(function (d) {
           //Finally this will work.
           alert(d)
    });
 2
Author: Hakkı Eser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-21 07:42:53

Inne odpowiedzi doskonale opisują to, co się dzieje, ale jednym z ważnych "mam cię" jest upewnienie się, że cokolwiek przechodzisz, jest rzeczywiście odniesieniem do funkcji.

Na przykład, jeśli przejdziesz przez ciąg znaków zamiast funkcji, otrzymasz błąd:

function function1(my_function_parameter){
    my_function_parameter();   
}

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

function1(function2); //This will work

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

Zobacz JsFiddle

 2
Author: Victor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-23 20:54:26

W pewnym momencie, kiedy musisz poradzić sobie z obsługą zdarzeń , więc musisz przekazać również zdarzenie jako argument, większość nowoczesnych bibliotek, takich jak react, angular, może tego potrzebować.

Muszę nadpisać funkcję OnSubmit (funkcję z biblioteki stron trzecich) z niestandardową walidacją na reactjs i przekazałem funkcję i Zdarzenie jak poniżej

Oryginalnie

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

Stworzył nową funkcję upload i wywołał przekazane onSubmit i zdarzenie jako argumenty

<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
Author: sumit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 23:56:09

Możesz również używać JSON do przechowywania i wysyłania funkcji JS.

Sprawdź:

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



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

To wydrukuje 'a'.

Poniższe ma ten sam efekt z powyższym:

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

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

function main(){
    myFunc2(myFunc1);
}

Który ma również ten sam efekt z następującym:

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


function myFunc2 (functionParameter){
    functionParameter();
}

function main(){
    myFunc2(myFunc1);
}

Oraz paradygmat obiektowy wykorzystujący klasę jako prototyp obiektu:

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
Author: gazgas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-09 08:18:01