Wie übergebe ich diesen Kontext an eine Funktion?

213

Ich dachte, das wäre etwas, das ich leicht googeln könnte, aber vielleicht stelle ich nicht die richtige Frage ...

Wie stelle ich ein, worauf sich "dies" in einer bestimmten Javascript-Funktion bezieht?

Zum Beispiel wie bei den meisten Funktionen von jQuery wie:

$(selector).each(function() {
   //$(this) gives me access to whatever selector we're on
});

Wie schreibe / rufe ich meine eigenen Standalone-Funktionen auf, die beim Aufruf eine entsprechende "this" -Referenz haben? Ich verwende jQuery. Wenn es also eine jQuery-spezifische Methode gibt, wäre dies ideal.

user126715
quelle
Mögliches Duplikat: stackoverflow.com/questions/520019/…
user123444555621
Ich weiß, dass dies eine alte Frage ist, aber für andere, die hier landen, siehe jQuery$.proxy
RyBolt

Antworten:

302

Mit Javascripts .call()und .apply()Methoden können Sie den Kontext für eine Funktion festlegen .

var myfunc = function(){
    alert(this.name);
};

var obj_a = {
    name:  "FOO"
};

var obj_b = {
    name:  "BAR!!"
};

Jetzt können Sie anrufen:

myfunc.call(obj_a);

Welches würde alarmieren FOO. Umgekehrt obj_bwürde das Vorbeigehen alarmieren BAR!!. Der Unterschied zwischen .call()und .apply()besteht darin, dass .call()eine durch Kommas getrennte Liste verwendet wird, wenn Sie Argumente an Ihre Funktion übergeben und .apply()ein Array benötigen.

myfunc.call(obj_a, 1, 2, 3);
myfunc.apply(obj_a, [1, 2, 3]);

Daher können Sie hookmit der apply()Methode einfach eine Funktion schreiben . Zum Beispiel möchten wir der jQuerys- .css()Methode ein Feature hinzufügen . Wir können die ursprüngliche Funktionsreferenz speichern, die Funktion mit benutzerdefiniertem Code überschreiben und die gespeicherte Funktion aufrufen.

var _css = $.fn.css;
$.fn.css = function(){
   alert('hooked!');
   _css.apply(this, arguments);
};

Da das magische argumentsObjekt ein Array-ähnliches Objekt ist, können wir es einfach an übergeben apply(). Auf diese Weise garantieren wir, dass alle Parameter an die ursprüngliche Funktion übergeben werden.

jAndy
quelle
4
Nur ein kleiner Leckerbissen: Wenn Sie die Funktion beispielsweise wiederholt aufrufen müssen obj_a, können Sie beispielsweise eine Kopie davon erstellen var boud_myfunc = myfunc.bind(obj_a)und bound_myfunc()bei Bedarf einfach aufrufen .
Badart
44

Verwendungfunction.call :

var f = function () { console.log(this); }
f.call(that, arg1, arg2, etc);

Wo thatist das Objekt, das Sie thisin der Funktion haben möchten ?

palswim
quelle
1
functionist ein reserviertes Schlüsselwort; Erwägen Sie, Ihre Antwort so zu aktualisieren, dass sie eine benannte Funktion enthält, da function.call(...)JavaScript nicht gültig ist.
Daniel Allen
1
@DanielAllen: Ohne die Definition des Beispielfunktionsnamens, den ich angeben würde, wird der Code immer noch einen JS-Fehler auslösen. Ich habe jedoch den Namen der Beispielfunktion aktualisiert.
Palswim
16

jQuery verwendet eine .call(...)Methode, um den aktuellen Knoten thisinnerhalb der Funktion zuzuweisen, die Sie als Parameter übergeben.

BEARBEITEN:

Haben Sie keine Angst, im Zweifelsfall in den Code von jQuery zu schauen. Alles ist in klarem und gut dokumentiertem Javascript.

dh: Die Antwort auf diese Frage ist um Zeile 574,
callback.call( object[ name ], name, object[ name ] ) === false

Mic
quelle
12

Sie können die Verwendung bind Funktion den Kontext setzen thisinnerhalb einer Funktion.

function myFunc() {
  console.log(this.str)
}
const myContext = {str: "my context"}
const boundFunc = myFunc.bind(myContext);
boundFunc(); // "my context"
Scott Jungwirth
quelle
12

Ein weiteres grundlegendes Beispiel:

Funktioniert nicht:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
};
img.src = reader.result;

Arbeiten:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
}.bind(this);
img.src = reader.result;

Also im Grunde: Fügen Sie einfach .bind (this) zu Ihrer Funktion hinzu

Joery
quelle
Dies sollte die akzeptierte Antwort sein. Viel einfachere Syntax, viel einfacher im Kopf ... gute Arbeit Joery
nenea