2015-05-19 8 views
6

In ES5, ich konnte die Existenz einer „Klasse“ (Konstruktor-Funktion) auf dem Fensterobjekt überprüfen:ES6-Klassen: Wie sieht es mit der Inspektion aus?

if (window.MyClass) { 
... // do something 
} 

In ES6, according to this article sind global deklarierte Klassen Globals, aber nicht Eigenschaften des globalen Objekts (window, auf Browser):

Aber es gibt jetzt auch globale Variablen, die nicht Eigenschaften des globalen Objekts sind. Im globalen Bereich schaffen die folgenden Erklärungen solcher Variablen:

  • let Erklärungen
  • const Erklärungen
  • Klassendeklarationen

Also, wenn ich nicht if (window.MyClass) verwenden können, ist es eine Möglichkeit, das Gleiche tun?

Gibt es tatsächlich einen richtigen Weg, dies zu tun, ohne Fensterobjekt zu verwenden?

+4

"bedeutet, dass sie im globalen Fensterbereich nicht zugänglich sind" ... Was hat das Hissen mit dem globalen Geltungsbereich zu tun? – elclanrs

+0

Danke für Ihre Antworten. In der Tat, Entschuldigung für die Verwirrung, nichts zu sehen mit dem Heben. Wie auch immer, hättest du irgendeine Empfehlung, nach dem Klassenleben zu suchen? es6 Module vielleicht? – Sam

+0

Überprüfen Sie, ob das Root-Modul, das die Klasse deklariert, deklariert wird? –

Antwort

6

In ES5, konnten wir die Existenz einer Klasse auf dem Fensterobjekt

Nur wheck wenn der Konstruktor-Funktion eine globale war, was eine schlechte Praxis.

In ES6, according to this article, global deklarierte Klassen sind Globals, aber nicht Eigenschaften des globalen Objekts ...

Richtig. (Das gleiche gilt für let und const Erklärungen auf globaler Tragweite.) Das in §8.1.1.4: Global Environment Records definiert:

Eine globale Umwelt Record ist logisch ein einzelner Datensatz, aber es wird als Verbund ein Objekt angegeben Umgebungsdatensatz Einkapselung und ein deklarativer Umgebungsdatensatz. Das Objekt Environment Record hat als Basisobjekt das globale Objekt des zugehörigen Realms. Dieses globale Objekt ist der Wert, der von der konkreten Methode GetThisBinding des globalen Umgebungsdatensatzes zurückgegeben wird. (zum Beispiel das globale Objekt von window auf Browser verwies   — TJ)Die Objektumgebung Bilanz Bestandteil eines globalen Umweltakte enthält die Bindungen für alle Einbau-Globals (Ziffer 18) und alle von einem FunctionDeclaration eingeführt Bindungen , GeneratorDeclaration oder VariableStatement im globalen Code enthalten. Die Bindungen für alle anderen ECMAScript-Deklarationen in globalem Code sind in der deklarativen Umgebungsdatensatzkomponente des globalen Umgebungsdatensatzes enthalten.

(Hervorhebung von mir) So sind die Dinge, die auf das globale Objekt in ES5 gehen verwendet und früher noch tun (plus Generatoren, weil es verwirrend noch mehr hätte, wenn sie nicht), aber die neuen Dinge (let, const und class Erklärungen) nicht. Sie sind Globals, aber keine Eigenschaften des globalen Objekts.

Zurück zu Ihrer Frage ...

Also, wenn ich nicht if (window.MyClass) verwenden kann, ist es eine Möglichkeit, das gleiche zu tun?

könnten Sie verwenden

if (typeof MyClass === "function") { 

... seit typeof auf einem unlösbaren Symbol kein ReferenceError wirft. Dies hat auch den Vorteil zu prüfen, ob MyClass im Umfang für den Code ist, auch wenn es nicht global ist.

Es gibt eine Gotcha es allerdings: Wenn dieser Code im gleichen Bereich ist, wo MyClass über class deklariert wird (oder let oder const), aber es ist obenMyClass in diesem Rahmen auch der typeof Scheck wird ein ReferenceError werfen, weil Sie können nicht auf die Bindung zugreifen, die es erstellt überhaupt (nicht einmal mit typeof) vor der class (oder let oder const).

Eg, wird dies werfen:

if (typeof MyClass === "function") { // ReferenceError here 
    // Yup, it's defined 
    // ... 
} 
// ... 
class MyClass { 
} 

Der Raum von Anfang des Geltungsbereichs auf die class, let oder const Linie Totzonen (TDZ) die zeitliche genannt wird und man nicht Greifen Sie auf die variable Bindung überhaupt zu. Folglich müssen Sie fangen die ReferenceError:

let exists = false; 
try { 
    exists = typeof MyClass === "function"; 
} catch (e) { 
} 

Eigentlich ist es eine richtige Art und Weise dieses Objekt ohne Fenster zu tun?

Bis JavaScript Module, die es zu breiten Browser-Unterstützung machen, gibt es ein paar Möglichkeiten:

  1. eine Asynchronous Module Definition Bibliothek irgendeiner Art verwenden Laden Sie Ihre Module zu handhaben. Einige Beispiele: RequireJS, SystemJS, CommonJS

  2. Verwenden Sie eine einzelne globale Variable, die Sie verwenden, um auf ein Objekt zu verweisen, und machen Sie Ihre verschiedenen globalen Anwendungseigenschaften dieses Objekts.Hier ist eine typische Art und Weise, das zu tun:

    var MyApp = MyApp || {}; 
    if (!MyApp.ThisModule) {     // You can leave this `if` out 
                  // if there's no chance of the file 
                  // being loaded more than once 
        MyApp.ThisModule = function(module) { 
         module.MyClass = class MyClass { 
          // ...class definition here... 
         } 
        }({}); 
    } 
    

Dies gibt Ihnen auch einen praktischen Rahmen (die anonyme Funktion), in dem alle Modulebene Globals zu setzen.

Verwandte Themen