Aus Dokumenten verstehe ich, dass .proxy()
dies den Umfang der als Argument übergebenen Funktion ändern würde. Könnte mir bitte jemand das besser erklären? Warum sollten wir das tun?
javascript
jquery
Aditya Shukla
quelle
quelle
Antworten:
Letztendlich wird sichergestellt, dass der Wert
this
einer Funktion der von Ihnen gewünschte Wert ist.Ein häufiges Beispiel ist ein
setTimeout
, das in einemclick
Handler stattfindet.Nimm das:
Die Absicht ist einfach genug. Wenn darauf
myElement
geklickt wird, sollte es die Klasse erhaltenaNewClass
. Im Handler befindet sichthis
das Element, auf das geklickt wurde.Aber was ist, wenn wir eine kurze Verzögerung wünschen, bevor wir die Klasse hinzufügen? Wir könnten a verwenden
setTimeout
, um dies zu erreichen, aber das Problem ist, dass unabhängig von der Funktion, die wir gebensetTimeout
, der Wertthis
innerhalb dieser Funktionwindow
anstelle unseres Elements liegt.Was wir stattdessen tun können, ist aufzurufen
$.proxy()
und ihm die Funktion und den Wert zu senden, denen wir zuweisen möchtenthis
, und es wird eine Funktion zurückgegeben, die diesen Wert beibehält.Nachdem wir
$.proxy()
die Funktion und den gewünschten Wert angegeben habenthis
, wurde eine Funktion zurückgegeben, die sicherstellt, dass siethis
richtig eingestellt ist.Wie macht es das? Es wird nur eine anonyme Funktion zurückgegeben, die unsere Funktion mit der
.apply()
Methode aufruft , mit der der Wert von explizit festgelegt werden kannthis
.Ein vereinfachter Blick auf die zurückgegebene Funktion könnte folgendermaßen aussehen:
Diese anonyme Funktion ist also gegeben
setTimeout
, und alles, was sie tut, ist, unsere ursprüngliche Funktion mit dem richtigenthis
Kontext auszuführen .quelle
$.proxy(function () {...}, this)
anstatt(function() {...}).call(this)
? Ist da ein Unterschied?.call
dir rufst du die Funktion sofort auf. Mit$.proxy
ist es so,Function.prototype.bind
als würde eine neue Funktion zurückgegeben. Bei dieser neuen Funktion ist derthis
Wert permanent gebunden, sodass sie bei Übergabe ansetTimeout
undsetTimeout
späterem Aufrufen der Funktion immer noch den richtigenthis
Wert hat.Ohne näher darauf einzugehen (was notwendig wäre, da es sich um den Kontext in ECMAScript, die Kontextvariable this usw. handelt)
Es gibt drei verschiedene Arten von "Kontexten" in ECMA- / Javascript:
Jeder Code wird in seinem Ausführungskontext ausgeführt . Es gibt einen globalen Kontext und es kann viele Instanzen von Funktionskontexten (und Bewertungskontexten) geben. Nun der interessante Teil:
Jeder Aufruf einer Funktion tritt in den Funktionsausführungskontext ein. Ein Ausführungskontext einer Funktion sieht folgendermaßen aus:
Die Aktivierung Object
Scope - Chain
diesen Wert
So ist der dieser Wert ist ein spezielles Objekt , das mit dem Ausführungskontext verwendet ist. In ECMA- / Javascript gibt es zwei Funktionen, die diesen Wert in einem Funktionsausführungskontext ändern können :
Wenn wir eine Funktion
foobar()
haben, können wir diesen Wert ändern , indem wir Folgendes aufrufen:Jetzt konnten wir auf
foobar
das Objekt zugreifen, das wir übergeben haben:Genau das
jQuery.proxy()
macht es. Es nimmt einfunction
undcontext
(das nichts anderes als ein Objekt ist) und verknüpft die Funktion durch Aufrufen von.call()
und.apply()
und gibt diese neue Funktion zurück.quelle
Ich habe diese Funktion geschrieben:
quelle
Das gleiche Ziel kann mit einer
selbstausführenden Funktion"Sofort aufgerufener Funktionsausdruck, kurz: IIFE" erreichtwerden:quelle