Was ist der Unterschied zwischen einer globalen Variablen und einer window.variable in Javascript?


74

Ich lese die Dokumente von backbone.js und sehe viel Code, der dem Fensterobjekt Attribute zuweist:

window.something = "whatever";

Was ist der Unterschied zwischen dem Aufrufen dieses Codes und dem Zuweisen der Variablen und dem Erstellen einer globalen Variablen wie folgt:

something = "whatever";

Ich gehe davon aus, dass es eine andere Art von Umfang und / oder Unterschied im Objektbesitz gibt (Fenster ist der Eigentümer gegenüber nicht), aber ich interessiere mich für das Detail zwischen den beiden und warum ich Fenster verwenden würde, anstatt es nicht zu verwenden.


2
Das ist wirklich nicht zu Ihrem speziellen Fall verwandt, aber nicht vergessen , dass Javascript nicht hat , um in einem Browser ausgeführt werden , so dass Fenster nicht funktioniert haben definiert werden.
Andrei Bârsan

Antworten:


73

Kein Unterschied. Sie haben beide den gleichen Effekt (Im Browser windowbefindet sich der globale Kontext 1 ).

  • window.foo = "bar"setzt die Eigenschaft fooauf window.
  • foo = "bar"zeigt entweder einen Tippfehler oder absichtlich global an.

Da ich noch einmal überprüfen muss, ob es sich um einen Tippfehler handelt oder nicht, finde ich es persönlich besser lesbar , ihn window.foodirekt einzustellen .

Außerdem ist im strengen ES5-Modus foo = "bar"eine unzulässige Zuweisung, da sie foonicht deklariert ist und a auslöst Error.

Bearbeiten:

Wie in den Kommentaren erwähnt, foo = "bar"wird die Gültigkeitsbereichskette für die Variable foovollständig durchsucht und neu zugewiesen, "bar"wenn sie gefunden wird. Wird es nicht gefunden, wird eine neue globale Variable erstellt.

Außerdem weisen window.foo = "bar"Sie einem Objekt nur eine Eigenschaft zu, die mit gelöscht werden kann delete window.foo.

In ES5 Strict - Modus ist es ungültig zu deleteeiner Variablen.


1 In anderen Umgebungen wie node.js und Web Workers gibt es möglicherweise einen anderen Namen für das globale Objekt und ist windowmöglicherweise überhaupt nicht vorhanden. Node.js verwendet globalund Web Worker verwenden self.


4
Nebenbei können Sie window.foo löschen, jedoch kein mit var definiertes globales foo.
kennebec

8
Da ist ein Unterschied. window.foo = bar;setzt foo auf das Fensterobjekt. foo = bar;Durchsucht die Bereichskette, bis sie gefunden wird foo, was möglicherweise das globale Objekt ist, aber nicht immer.
David

@kennebec Ich glaube, das ist browserspezifisch.
Raynos

@ Raynos: Der Unterschied beim Löschen ist nicht wirklich browserspezifisch. Gemäß der ECMAScript-Spezifikation und unter windowder Annahme, dass es sich um das globale Objekt handelt, ist das von @kennebec beschriebene Verhalten korrekt. Ältere Versionen des IE stimmen jedoch nicht überein.
Tim Down

@ TimDown Es soll nicht browserspezifisch sein, ist es aber. Ich stimme jedoch zu, dass die ES-Spezifikation besagt, dass Sie Eigenschaften löschen können.
Raynos

10

Beide machen das Gleiche. Wenn Sie jedoch
auf eine windowEigenschaft zugreifen , wissen Sie sicher, dass Sie auf eine globale Variable zugreifen, unabhängig davon, in welchem ​​Bereich Sie sich befinden.
Beispiel:

globalVar = "smth";
function(){
    var globalVar = 2;
    alert(globalVar);// points to the current scope globalVar
    alert(window.globalVar);// points to the original globalVar
}

Mit anderen Worten: Wenn Sie mit Globals arbeiten möchten, ist es etwas sicherer, über deren Container auf sie zuzugreifen: window.variable


5

Der Schlüssel ist, wie Raynos anspielte, dass er explizit für das Fensterobjekt festgelegt wird. Im Browser ist das globale Objekt dasselbe wie das Fensterobjekt, in anderen Umgebungen (z. B. node.js oder in einer Webansicht auf einem mobilen Gerät) möglicherweise nicht.


2

Der Unterschied besteht darin, dass ein window.foo = bar;späteres Refactoring nicht abgefangen werden kann. Verwenden foo = bar;bedeutet, dass der Code, wenn er zu einem späteren Zeitpunkt in einen definierten Abschluss verschoben var foowird, nicht mehr für das globale Objekt festgelegt wird.


0

Einen weiteren Punkt hinzufügen:

Wenn Sie eine nicht deklarierte Variable direkt referenzieren (ohne - window oder typeof zu verwenden ), erhalten Sie eine Variable, deren Fehler nicht definiert ist .

Beispiele:

// var unDecVariable

if (unDecVariable != null) // Error: unDecVariable is not defined
{
    // do something
}

if (window.unDecVariable != null) // No Error
{
    // do something
}

if (typeof unDecVariable != 'undefined' && unDecVariable != null) // Alternative way
{
    // do something
}

0

Nicht aufgelöste Referenzen (auch als nicht deklarierte Variablen bezeichnet) sind eigentlich keine Variablen. Sie werden dem globalen Objekt als Eigenschaft hinzugefügt. [5c]

Im strengen Modus ("use strict") lösen ungelöste Referenzen einen ReferenceError aus. Dies soll verhindern, dass dem globalen Objekt Eigenschaften hinzugefügt werden, die als deklarierte Variablen gedacht waren. In diesem Fall würden Sie window.foo = "bar" verwenden, wenn Sie dem globalen Objekt eine Eigenschaft hinzufügen möchten. [5a]

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.