Eine Funktion mit Parametern als Parameter übergeben?

151

Ist es möglich, eine Javascript-Funktion mit Parametern als Parameter zu übergeben?

Beispiel:

$(edit_link).click( changeViewMode( myvar ) );
Lucia
quelle
5
Es sieht aus wie JQuery und ist es höchstwahrscheinlich, aber das ist irrelevant. Die Verwendung oder Parameter und Funktionen sind unabhängig von den verwendeten Javascript-Bibliotheken gleich.
Guffa
@ Guffa - Ich habe mich gefragt, ob es mit jQuery
Russ Cam
1
@Lucia Bitte beachten Sie die akzeptierte Antwort auf veränderte dies .
Michał Perłakowski
Wenn Sie mit React arbeiten, ziehen Sie stackoverflow.com/questions/41369497/… in
Michael Freidgeim

Antworten:

244

Verwenden Sie einen "Verschluss":

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

Dadurch wird ein anonymer temporärer Funktions-Wrapper erstellt, der den Parameter kennt und an die eigentliche Callback-Implementierung übergibt.

Ferdinand Beyer
quelle
3
Wenn Sie eine Funktion für ein Objekt aufrufen möchten, müssen Sie bind () aufrufen. myObj.click (function () {this.doSomething ();} .bind (myObj)); Das wird "dies" zu myObj machen.
Eli
1
Ist das nicht ein Leistungsproblem, wenn es um viele davon geht? Beispiel: Sie rendern eine onPress in einer Zeile und haben 10.000 Zeilen. Dadurch wird für jede Zeile ein neuer anonymer temporärer Funktions-Wrapper erstellt. Gibt es eine andere Möglichkeit, dies zu tun?
Joshua Pinter
@JoshuaPinter Die Technik selbst ist kein Problem. Wenn Sie denselben Funktionsaufruf 10.000 Mal benötigen, können Sie den Wrapper einfach in einer Variablen speichern, sodass Sie ihn nur einmal erstellen. Wenn Sie 10.000 verschiedene Kontexte übergeben müssen, können Sie wenig tun. Vorsicht vor vorzeitiger Optimierung: Wie immer bei der Leistung müssen Sie messen , ob ein Problem vorliegt oder nicht. Die heutigen JavaScript-Engines sind sehr leistungsfähig und können den Code auf überraschende Weise optimieren.
Ferdinand Beyer
@FerdinandBeyer Super, danke für den Tipp. Ein Freund sagte mir, es sei eine schlechte Praxis und Sie sollten sie stattdessen this.myFunction = this.myFunction.bind(this)in Ihrer constructorMethode verwenden. Wie Sie bereits sagten, ist es jedoch nicht vermeidbar, wenn Sie für jede Zeile unterschiedliche Kontexte übergeben müssen, z. B. alle unterschiedlichen Zeilen, auf die Sie klicken, um die Detailseite dieser Zeile zu öffnen.
Joshua Pinter
@FerdinandBeyer, sagen sich mal myvar ist ein String und sein zwischen zwei aufeinander folgenden Anrufungen vorbei changeViewMode als Verschluss geändert, aber changeViewMode erhält immer den ersten Wert von myvar ich mit unterschiedlichem Argumentwert zu Call Verschlussfunktion will gleich myvar Variablen zugewiesen,
nmxprime
42

Verwenden Function.prototype.bind() . MDN zitieren:

Das bind() Methode erstellt eine neue Funktion, deren thisSchlüsselwort beim Aufruf auf den angegebenen Wert gesetzt wird, wobei eine bestimmte Folge von Argumenten vor allen beim Aufruf der neuen Funktion angegebenen Argumenten steht.

Es wird von allen gängigen Browsern unterstützt, einschließlich IE9 +.

Ihr Code sollte folgendermaßen aussehen:

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

Randnotiz: Ich gehe davon aus, dass Sie sich im globalen Kontext befinden, dh thisVariable ist window; andernfalls thisanstelle von verwenden null.

Michał Perłakowski
quelle
Danke, das hat mir geholfen. Verwendet es so:$.ajax(url).done(handler.bind(this, var1, var2));
Thomas
2
Welche Option ist am besten? Verwenden Sie den Verschluss oder die Bindefunktion? Bitte lassen Sie mich wissen, wenn es irgendwelche Auswirkungen auf die Leistung gibt
Varun
5
@Varun Siehe Warum ist die Bindung langsamer als ein Verschluss?
Michał Perłakowski
15

Nein, aber Sie können einen ohne Parameter übergeben und dies tun:

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

Wenn Sie also eine anonyme Funktion ohne Parameter übergeben, ruft diese Funktion Ihre parametrisierte Funktion mit der Variablen im Abschluss auf

Clyde
quelle
8

Ja genau so:

$(edit_link).click(function() { changeViewMode(myvar) });
Philippe Leybaert
quelle
7

Oder wenn Sie es6 verwenden, sollten Sie in der Lage sein, eine Pfeilfunktion zu verwenden

$(edit_link).click(() => changeViewMode(myvar));
Christian Bartram
quelle
2

Du kannst das

var message  = 'Hello World';

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

und dann

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

activate(callback);

Wenn Ihr Rückruf eine flexiblere Logik enthält, können Sie ein Objekt übergeben.

Demo

Alexandr Sargsyan
quelle
2

Dies ist ein Beispiel nach dem Ansatz von Ferdinand Beyer:

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

In diesem Beispiel wird der "Parameterwert" mithilfe eines Funktionsumbruchs von Funktion1 zu Funktion3 über Funktion2 übergeben.

erionpc
quelle