Das Problem beim Versuch herauszufinden, in welcher Umgebung Ihr Code ausgeführt wird, besteht darin, dass jedes Objekt geändert und deklariert werden kann, sodass es nahezu unmöglich ist, herauszufinden, welche Objekte in der Umgebung nativ sind und welche vom Programm geändert wurden.
Es gibt jedoch einige Tricks, mit denen wir herausfinden können, in welcher Umgebung Sie sich befinden.
Beginnen wir mit der allgemein akzeptierten Lösung, die in der Unterstrichbibliothek verwendet wird:
typeof module !== 'undefined' && module.exports
Diese Technik ist für die Serverseite eigentlich vollkommen in Ordnung, da beim require
Aufrufen der Funktion das this
Objekt auf ein leeres Objekt zurückgesetzt und module
für Sie neu definiert wird, sodass Sie sich keine Gedanken über Manipulationen von außen machen müssen. Solange Ihr Code mit geladen ist require
, sind Sie sicher.
Dies fällt jedoch im Browser auseinander, da jeder leicht definieren kann module
, dass es so aussieht, als wäre es das Objekt, nach dem Sie suchen. Dies kann einerseits das gewünschte Verhalten sein, bestimmt aber auch, welche Variablen der Bibliotheksbenutzer im globalen Bereich verwenden kann. Vielleicht hat jemand will eine Variable mit dem Namen verwenden module
, der hat exports
in der es für eine andere Verwendung. Es ist unwahrscheinlich, aber wer sollen wir beurteilen, welche Variablen jemand anderes verwenden kann, nur weil eine andere Umgebung diesen Variablennamen verwendet?
Der Trick ist jedoch, dass, wenn wir davon ausgehen, dass Ihr Skript im globalen Bereich geladen wird (was auch der Fall ist, wenn es über ein Skript-Tag geladen wird), eine Variable nicht in einem äußeren Abschluss reserviert werden kann, da der Browser dies nicht zulässt . Denken Sie nun daran, dass das this
Objekt im Knoten ein leeres Objekt ist und die module
Variable dennoch verfügbar ist. Das liegt daran, dass es in einem äußeren Verschluss deklariert ist. So können wir den Check des Unterstrichs korrigieren, indem wir einen zusätzlichen Check hinzufügen:
this.module !== module
Wenn jemand module
im Browser den globalen Bereich deklariert , wird er im this
Objekt platziert, wodurch der Test fehlschlägt, da er this.module
dasselbe Objekt wie das Modul ist. Auf dem Knoten ist this.module
nicht vorhanden und module
befindet sich innerhalb eines äußeren Verschlusses, sodass der Test erfolgreich ist, da sie nicht gleichwertig sind.
Somit ist der letzte Test:
typeof module !== 'undefined' && this.module !== module
Hinweis: Auf diese Weise kann die module
Variable jetzt im globalen Bereich frei verwendet werden. Sie können dies jedoch im Browser umgehen, indem Sie einen neuen Abschluss erstellen und diesen deklarieren module
und dann das Skript in diesen Abschluss laden. Zu diesem Zeitpunkt repliziert der Benutzer die Knotenumgebung vollständig und weiß hoffentlich, was er tut, und versucht, einen erforderlichen Knotenstil auszuführen. Wenn der Code in einem Skript-Tag aufgerufen wird, ist er weiterhin vor neuen äußeren Verschlüssen geschützt.