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 requireAufrufen der Funktion das thisObjekt auf ein leeres Objekt zurückgesetzt und modulefü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 exportsin 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 thisObjekt im Knoten ein leeres Objekt ist und die moduleVariable 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 moduleim Browser den globalen Bereich deklariert , wird er im thisObjekt platziert, wodurch der Test fehlschlägt, da er this.moduledasselbe Objekt wie das Modul ist. Auf dem Knoten ist this.modulenicht vorhanden und modulebefindet 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 moduleVariable jetzt im globalen Bereich frei verwendet werden. Sie können dies jedoch im Browser umgehen, indem Sie einen neuen Abschluss erstellen und diesen deklarieren moduleund 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.