Passare una funzione con parametri come parametro?


151

È possibile passare una funzione JavaScript con parametri come parametro?

Esempio:

$(edit_link).click( changeViewMode( myvar ) );

5
Sembra JQuery, e molto probabilmente lo è, ma è irrilevante. L'uso, i parametri e le funzioni sono gli stessi indipendentemente dalle librerie Javascript utilizzate.
Guffa,

@Guffa - Mi chiedevo se dovesse essere taggato con jQuery
Russ Cam

1
@Lucia Ti preghiamo di considerare di cambiare la risposta accettata a questo .
Michał Perłakowski,

Se si lavora con Reagire, in considerazione stackoverflow.com/questions/41369497/...
Michael Freidgeim

Risposte:


244

Usa una "chiusura":

$(edit_link).click(function(){ return changeViewMode(myvar); });

Ciò crea un wrapper di funzioni temporanee anonime che conosce il parametro e lo passa all'implementazione di callback effettiva.


3
Se vuoi chiamare una funzione su un oggetto, devi chiamare bind (). myObj.click (function () {this.doSomething ();} .bind (myObj)); Ciò renderà "questo" essere myObj.
Eli,

1
Non è questo un problema di prestazioni quando si affrontano molti di questi? Ad esempio stai eseguendo il rendering di un onPress in una riga e hai 10.000 righe. Ciò crea un nuovo wrapper di funzioni temporanee anonime per ogni riga. c'è un altro modo per farlo?
Joshua Pinter,

@JoshuaPinter La tecnica in sé non è un problema. Se hai bisogno della stessa funzione di chiamata 10.000 volte, puoi semplicemente salvare il wrapper in una variabile, quindi puoi crearlo una sola volta. Se devi superare 10.000 contesti diversi, c'è poco che puoi fare. Attenzione all'ottimizzazione precoce: come sempre con le prestazioni, è necessario misurare per vedere se c'è un problema o meno. I motori JavaScript di oggi sono molto potenti e potrebbero ottimizzare il codice in modi sorprendenti.
Ferdinand Beyer,

@FerdinandBeyer Fantastico, grazie per il suggerimento. Un amico mi ha detto che era una cattiva pratica e che invece dovresti usare this.myFunction = this.myFunction.bind(this)nel tuo constructormetodo. Ma, come hai detto, quando devi passarci contesti diversi per ognuno, come tutte le diverse righe su cui fai clic per aprire la pagina dei dettagli di quella riga, non è evitabile.
Joshua Pinter,

@FerdinandBeyer, supponiamo che myvar sia una stringa e sia cambiata tra due invocazioni consecutive di passaggio changeViewMode come chiusura, ma changeViewMode riceve sempre il primo valore di myvar, voglio chiamare la funzione di chiusura con diverso valore argomento assegnato alla stessa variabile myvar,
nmxprime,

42

Usa Function.prototype.bind(). Citando MDN:

Il bind()metodo crea una nuova funzione che, quando viene chiamata, ha la thisparola chiave impostata sul valore fornito, con una determinata sequenza di argomenti che precede quella fornita quando viene chiamata la nuova funzione.

È supportato da tutti i principali browser, incluso IE9 +.

Il tuo codice dovrebbe apparire così:

$(edit_link).click(changeViewMode.bind(null, myvar));

Nota a margine: suppongo che tu sia in un contesto globale, cioè che la thisvariabile sia window; altrimenti usa thisinvece di null.


Grazie, questo mi ha aiutato. Usata così:$.ajax(url).done(handler.bind(this, var1, var2));
Thomas

2
Quale opzione è la migliore? Usando la chiusura o usando la funzione bind? Per favore fatemi sapere se c'è qualche impatto sulle prestazioni
Varun


15

No, ma puoi passarne uno senza parametri e procedere come segue:

$(edit_link).click(
  function() { changeViewMode(myvar); }
);

Quindi stai passando una funzione anonima senza parametri, tale funzione chiama quindi la tua funzione parametrizzata con la variabile nella chiusura



7

O se stai usando es6 dovresti essere in grado di usare una funzione freccia

$(edit_link).click(() => changeViewMode(myvar));

2

Puoi farlo

var message  = 'Hello World';

var callback = function(){
alert(this)
}.bind(message);

e poi

function activate(callback){
  callback && callback();
}

activate(callback);

Oppure, se il callback contiene una logica più flessibile, è possibile passare l'oggetto.

dimostrazione


2

Questo è un esempio che segue l'approccio di Ferdinand Beyer:

function function1()
{
    function2(function () { function3("parameter value"); });
}
function function2(functionToBindOnClick)
{
    $(".myButton").click(functionToBindOnClick);
}
function function3(message) { alert(message); }

In questo esempio il "valore del parametro" viene passato dalla funzione1 alla funzione3 attraverso la funzione2 usando una funzione a capo automatico.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.