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:
eine Asynchronous Module Definition Bibliothek irgendeiner Art verwenden Laden Sie Ihre Module zu handhaben. Einige Beispiele: RequireJS, SystemJS, CommonJS
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.
"bedeutet, dass sie im globalen Fensterbereich nicht zugänglich sind" ... Was hat das Hissen mit dem globalen Geltungsbereich zu tun? – elclanrs
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
Überprüfen Sie, ob das Root-Modul, das die Klasse deklariert, deklariert wird? –