2016-07-23 7 views
1

In dem folgenden Code:Javascript: Warum haben Callback-Funktionen mit globalem Ausführungskontext Zugriff auf Bereichsvariablen?

function test() { 
    var x = 5 // scoped to test function 
    console.log(this); // global object 
    logCb(function(){ 
     console.log(this); // global object 
     console.log(x); 
    }) 
} 

function logCb (cb) { 
    console.log(this); // global object 
    cb() // This still seems to execute within the test function scope? why... 
} 

test() 

x wird zu testen scoped, und dies ist, wo die Callback-Funktion definiert ist. Ich hätte erwartet, Linie cb() einen Fehler zu werfen, da die Funktion logCb() keinen Zugriff auf die Variable x hat.

Dies ist jedoch nicht der Fall. Warum? Es scheint, als ob Referenzen innerhalb des Callbacks während der Zuweisung und NICHT während der Ausführung erzeugt werden - was ich denke, wenn man das Hochziehen berücksichtigt - dh während der Kompilierung wird die Callback-Funktion an die Spitze von 'test' gehievt und dann erfolgt die Zuweisung innerhalb von Tests Umfang?

Ich habe gelesen, dass die Ausführung nicht das gleiche wie der Geltungsbereich ist. In diesem Artikel: http://ryanmorr.com/understanding-scope-and-context-in-javascript/ scheint dieser Satz scope pertains to the variable access of a function when it is invoked and is unique to each invocation zu implizieren, dass der Rückruf innerhalb der Testfunktion aufgerufen wird.

Da es scheint mir, dass egal, wo die Callback-Funktion aufgerufen wird, wäre es immer noch zu testen.

Ich denke, meine Frage ist:

Wie wird die Callback-Funktion in Bezug auf die Definition behandelt und dann Aufruf, wenn man über Umfang und Ausführungskontext gedacht?

+0

Haben Sie schon einmal über Schließungen in Javascript gehört? –

+0

Der Umfang einer Funktion hängt vollständig davon ab, wo sie * deklariert * ist und nicht wo sie aufgerufen wird. Das 'this 'einer Funktion steht nicht im Zusammenhang mit dem Bereich und basiert auf * wie * die Funktion aufgerufen wird. – nnnnnn

+0

@RajaprabhuAravindasamy. Also hat der Callback den Test geschlossen? –

Antwort

1

Wie wird die Callback-Funktion in Bezug auf die Definition und dann Aufruf behandelt, wenn über den Umfang und Ausführungskontext nachgedacht wird?

wird ein Funktionsumfang auf, wo es

Erklärung in der lexikalischen Umgebung physikalisch vorhanden ist: Der Rückruf ist lexikalisch in dem Funktionstest(), so ist es immer zu finden versuchen, der Wert von diese entweder in sich selbst (falls vorhanden), sonst wird es seinen Wert in der äußeren Umgebung sehen (die Funktionstest ist in diesem Fall)

Die Testfunktion und LogCb Funktion wird die gleiche Praxis folgen. In diesem Fall wird die äußere Umgebung global

sein, wie der Motor den Überblick über Umfang halten nicht separat Ausführung Kontext?

lexikalische Umgebung: Wo etwas physisch im Code sitzt Sie schreiben.

Ausführungskontext: Ein Wrapper zur Verwaltung des ausgeführten Codes.

Jetzt in Ihrem Code gibt es viele lexikalische Umgebungen. Welche gerade ausgeführt wird, wird über Ausführungskontexte verwaltet. Es kann Dinge enthalten, die über das hinausgehen, was Sie in Ihrem Code geschrieben haben.

Wenn Ausführungskontext erstellt haben wir drei Dinge, die uns zur Verfügung stehen:

  1. Globales Objekt (Fenster): Jede Variable oder Funktion im globalen Bereich zu Fensterobjekt verknüpft ist
  2. ‚this‘
  3. äußere Umgebung

Also je nachdem, welche Ausführungskontext derzeit ausgeführt wird, werden diese Dinge variieren je, wo es physisch oder lexikalisch in Code. Zum Beispiel kann die äußere Umgebung für cb ist die function test()

+0

Wie verfolgt die Engine den Bereich separat zum Ausführungskontext? –

1

Scope durch bestimmt wird, in dem eine Funktion ist geschaffen, nicht durch, wo sie aufgerufen wird.

Die Funktion, die Sie an logCb übergeben, wird innerhalb test erstellt, so hat es Zugriff auf test 's Bereich.

+0

Kennen Sie eine gute Erklärung dafür, wie die Google V8-Engine dies erzwingt? –

1

Wenn eine Funktion in Javascript aufgerufen wird, wird ein Kontext an sie übergeben.

Der Kontext eine der folgenden Möglichkeiten sein kann

  1. mit neuem, wird ein temporäres Objekt erstellt und es wird als Kontext für die Funktion

  2. Aufruf Funktion über das Objekt a.getValue geben (). getValue erhält den Kontext ein

  3. wenn keine der oben genannten 2 passieren das globale Objekt dh Fenster