Klärung von Schließungen in Javascript mit AJAX

8

Ich soll Cloures in Javascript richtig verstanden haben, aber offensichtlich nicht ...

Im Moment hat der Text, den ich gerade lese, diese Funktion, um einen AJAX-Aufruf zu abstrahieren:

%Vor%

Hier ist mein eigentliches Problem: Mein Gehirn weigert sich zu verstehen, warum dieses nicht funktionieren würde:

%Vor%

Ich meine, auf "meine" Weise, was ich mir vorstellen würde, ist, dass ich sage say request ('http: // ...', a_callback). Innerhalb von request () wird ein neues xhr-Objekt erstellt und es wird dem Callback zugewiesen ... würde es nicht funktionieren? Was wären die (unangenehmen) Nebenwirkungen? Aus meinem (begrenzten) Verständnis heraus benötigen Sie Closures, wenn Sie sich beispielsweise in einem Zyklus auf den letzten Wert einer Funktionsvariablen beziehen. Aber hier ... stellt das "var xhr = ..." nicht sicher, dass jedes Mal ein neues Objekt erstellt wird?

Bitte erläutern Sie, als hätte ich einen IQ von 30 (was wahrscheinlich wahr ist: D) ​​

Merc.

    
Merc 30.10.2011, 15:23
quelle

7 Antworten

9

Sie benötigen diesen zusätzlichen Abschluss im ersten Beispiel nicht. Das funktioniert gut:

%Vor%

In modernen Browsern (oder Browsern gepatcht mit einem Polyfill ) könnten Sie das auch tun das:

%Vor%

edit - Beachten Sie auch die Antwort @Raynos zur Verfügung gestellt. Sie müssen das XHR-Objekt nicht wirklich als Parameter übergeben.

nochmal bearbeiten - als Antwort auf einen legitimen Kommentar haben Sie gefragt, warum Ihre ursprüngliche Idee nicht funktionieren würde:

%Vor%

Das Problem ist mit der Zeile hier:

%Vor%

Dies weist dem onreadystatechange den Wert zurück, der von einem Aufruf an die Callback-Funktion zurückgegeben wurde. Mit anderen Worten, anstatt dass etwas eingerichtet wird, das angerufen wird, wenn sich der Zustand ändert, wird der Anruf sofort getätigt. Dieser Fehler ist wirklich üblich, weil es leicht zu lesen ist. Zu jeder Zeit sieht JavaScript jedoch eine Funktionsreferenz, gefolgt von einer Argumentliste in Klammern, die als Anforderung zum Ausführen des Funktionsaufrufs interpretiert wird, und nicht als Anforderung eines Funktionswrappers für einen zukünftigen Funktionsaufruf.

    
Pointy 30.10.2011, 15:27
quelle
6

Wenn Sie xhr.onreadystatechange = callback(xhr) schreiben, rufen Sie sofort callback auf und weisen ihr Ergebnis onreadystatechange zu.

    
SLaks 30.10.2011 15:25
quelle
1

In dem Code, den du zeigst, rufst du callback an wegen des () am Ende.

    
Dave Newton 30.10.2011 15:26
quelle
1

Gute Frage. Es gibt einen wichtigen Unterschied zwischen einem Funktionsaufruf und einem Zeiger auf eine Funktion - Sie möchten ihnen einen Zeiger auf eine Funktion geben (nicht wirklich, es ist eine Schließung, aber das nenne ich es so), damit sie es später aufrufen können . Das ist wirklich wichtig, wenn Sie jemals funktionale Programmierung machen oder mit irgendetwas in der Lisp-Familie spielen.

    
Dan 30.10.2011 15:28
quelle
1

In C und den meisten anderen gebräuchlichen Sprachen nach dem Zurückgeben einer Funktion sind alle lokalen Variablen nicht mehr zugänglich, da der Stapelrahmen zerstört wird.

Wenn Sie in JavaScript eine Funktion innerhalb einer anderen Funktion deklarieren, können die lokalen Variablen auch nach der Rückkehr von der von Ihnen aufgerufenen Funktion zugänglich bleiben.

    
Yola 30.10.2011 15:29
quelle
1

Sie müssen xhr nicht an den Callback übergeben.

Sie können einfach xhr.onreadystatechange = callback;

tun

und verwenden Sie this , um auf das xhr -Objekt innerhalb des Callbacks zu verweisen.

Beispiel:

%Vor%

Haftungsausschluss: Für einen gewissen Wert der Cross-Browser-Unterstützung & gt; _ & gt;

    
Raynos 30.10.2011 15:28
quelle
0

Ich beantworte meine eigene Frage, weil die Bearbeitung alles verwirren würde - bitte entschuldigen Sie, wenn das nicht der richtige Weg ist.

Also ... Was ich eigentlich schreiben wollte, ist in meinem Beispiel:

%Vor%

Oder, da ich xhr nicht brauche (ich kann "das" verwenden):

%Vor%

Also, am Ende hatte ich recht ... die Verwendung einer Schließung (wie in der ursprünglichen Frage gesehen) ist eine völlige Zeitverschwendung, richtig?

Es wäre wichtig gewesen, wenn es einen Zyklus gegeben hätte, und ich musste mehrere Rückrufe setzen. Aber in diesem Fall, da eine neue xhr jedes Mal erstellt wird, wenn "request" aufgerufen wird, und es mit dem richtigen Callback gesetzt ist, besteht keine Notwendigkeit, eine Schließung zu haben .. right?

Merc.

    
Merc 31.10.2011 01:05
quelle

Tags und Links