wake-up-neo.com

Ist Windows in Javascript wirklich global?

Nehmen Sie dieses Stück Javascript in einen Browser:

<script>

console.log(window.someThing);
var x = 12;

function foo() {
   window.otherThing = x;
}

</script>

In foo können wir auf window zugreifen, das wissen wir alle, aber warum genau?

  • Ist es eine Art spezielle globale Variable?
  • Oder hat der "root scope" (innerhalb des script-Tags) ihn als implizite lokale Variable und ist er einfach "schließungsvererbt", wie es jede andere lokale Variable (wie oben x) kann?

Und wie stimmt das mit Variablen überein, die direkt im Tag script deklariert wurden und als Eigenschaften von window festgelegt wurden? (Oder ist das nicht so?)

<script>
var x = 12;
function() {
   console.log(window.x);
}
</script>
25

Der Grund, warum Sie in ECMAscript auf "out of scope" oder "free" Variablen zugreifen können, ist die so genannte Scope chain . Die Scope-Kette ist eine spezielle Eigenschaft aus jedem Ausführungskontext . Wie bereits mehrfach erwähnt, sieht ein Kontextobjekt mindestens so aus:

  • [[Umfang]]
  • Variable/Aktivierungsobjekt
  • "dieser" Kontextwert

jedes Mal, wenn Sie auf eine Variable (-name) innerhalb eines Kontexts (beispielsweise eine Funktion) zugreifen, beginnt der Suchvorgang mit einem eigenen Activation Object. Alle Formalparameter, Funktionsdeklarationen und lokal definierten Variablen (var) werden in diesem speziellen Objekt gespeichert. Wenn der Variablenname in diesem Objekt nicht gefunden wurde, erfolgt die Suche in der [[Scope]]- Kette. Bei jeder Initialisierung einer Funktion (-context) werden alle übergeordneten Kontextvariablen/Aktivierungsobjekte in die interne Eigenschaft [[Scope]] kopiert. Das nennen wir einen lexikalischen Bereich . Das ist der Grund, warum Closures in ECMAscript arbeiten. Da der Global context auch einen Variable Object enthält (genauer gesagt **, das variable Objekt für das globale Objekt ist das globale Objekt selbst), wird er auch in die Eigenschaft [[Scope]] kopiert.

Das ist der Grund, warum Sie von jeder Funktion aus auf window zugreifen können :-)

Die obige Erklärung hat eine wichtige konzeptionelle Schlussfolgerung: Jede Funktion in ECMAscript ist ein Closure , was wahr ist. Da jede Funktion mindestens den globalen Kontext VO in seine [[Scope]] -Eigenschaft kopiert.

22
jAndy

Ist Windows in Javascript wirklich global?

Ja. Es sei denn, Sie erstellen eine neue Variable mit dem Namen window in einem engeren Bereich

function foo() {
    var window;
}

Innerhalb von foo können wir auf Fenster zugreifen, das wissen wir alle, aber warum genau?

Jede Funktion kann auf Variablen zugreifen, die in einem breiteren Bereich deklariert sind. Fenster haben dort nichts Besonderes.

14
Quentin

Es ist alles in ECMAScript definiert.

Das Globale ist eine lexikalische Umgebung, in der es keine äußere lexikalische Umgebung gibt. Alle anderen Umgebungen sind darin verschachtelt und an ein globales Objekt mit den in der Spezifikation angegebenen Eigenschaften gebunden.

Dadurch werden die Eigenschaften des globalen Objekts am Anfang der Bereichskette platziert, von der alle anderen Umgebungen erben.

ES 10.2.3 Die globale Umwelt :

Die globale Umgebung ist eine eindeutige lexikalische Umgebung, die erstellt wird, bevor ECMAScript-Code ausgeführt wird. Der Umgebungsdatensatz der globalen Umgebung ist ein Objektumgebungsdatensatz, dessen Bindungsobjekt das globale Objekt ist (15.1). Die Referenz für die äußere Umgebung der globalen Umgebung ist null.

Während der Ausführung von ECMAScript-Code können dem globalen Objekt zusätzliche Eigenschaften hinzugefügt und die ursprünglichen Eigenschaften geändert werden.

ES 15.1 Das globale Objekt

Das eindeutige globale Objekt wird erstellt, bevor die Steuerung in einen Ausführungskontext eintritt.

Sofern nicht anders angegeben, weisen die integrierten Standardeigenschaften des globalen Objekts die Attribute {[[Beschreibbar]]: true, [[Aufzählbar]]: false, [[Konfigurierbar]]: true} auf.

Das globale Objekt hat keine interne Eigenschaft [[Construct]]. Es ist nicht möglich, das globale Objekt als Konstruktor mit dem neuen Operator zu verwenden.

Das globale Objekt hat keine interne Eigenschaft [[Call]]. Es ist nicht möglich, das globale Objekt als Funktion aufzurufen.

Die Werte der internen Eigenschaften [[Prototype]] und [[Class]] des globalen Objekts sind implementierungsabhängig.

Zusätzlich zu den in dieser Spezifikation definierten Eigenschaften verfügt das globale Objekt möglicherweise über zusätzliche vom Host definierte Eigenschaften. Dies kann eine Eigenschaft umfassen, deren Wert das globale Objekt selbst ist. Beispielsweise ist im HTML-Dokumentobjektmodell die Fenstereigenschaft des globalen Objekts das globale Objekt selbst.

7
user113716

Es hat mit scope chain zu tun.

Schauen Sie sich die folgende Präsentation von Nicholas C. Zakas an . (ab ca. 5 min)

6
Saxoier

window ist der Basisbereich aller Javascript-Objekte und wird automatisch an jede von Ihnen definierte Variable "angehängt", es sei denn, Sie verwenden "var" vor der Deklaration übergeordnete Funktion oder auch sonst global, wenn Sie Ihre Variable außerhalb eines Funktionsblocks deklarieren). Außerdem ist window als Konstante definiert , dh Sie können das Fensterobjekt nicht neu definieren (Sie erhalten die Fehlermeldung "Typfehler: Neudeklaration von const window").

so:

window.foo = 5;

es ist das gleiche wie:

var foo = 5;

oder:

function() {
foo = 5;
}

aber:

function() {
var foo = 5;
}

in diesem Fall ist "foo" lokal (window.foo === undefined)

4
daveoncode

Der globale Bereich window gilt nur für den Haupt-Thread. In Web Workern gibt es keine window globale Variable. Stattdessen haben Sie WorkerGlobalScope IN EINER WebWorker und in einer SharedWorkerGlobalScope IN EINER SharedWorker .

Dieser globale Arbeitsbereich wird in einer Variablen namens self gespeichert und wie MDN es beschreibt:

dieser Gültigkeitsbereich enthält die Informationen, die normalerweise von Window Objekten übermittelt werden.

Dies kann zu einem Problem werden, wenn Code von Drittanbietern, den Sie in Ihrem Web-Worker verwenden, das Fensterobjekt verwendet. Dies kann leicht gelöst werden, indem eine window Variable deklariert wird, wie dies von @FelipeMicaroniLalli in seiner Antwort hier vorgeschlagen wird:

var window = self;
1
Wilt

In dem Buch Javascript: The Good Parts erklärt Douglas Crockford, dass window das globale Objekt des Webbrowsers ist, das alle globalen Variablen enthält. Es ist wie der Eine Ring ...

0
Vithozor