It’s #FrontendFriday – Strukturiere deinen Code in JavaScript unter der Verwendung von ES5

26.02.2021

Hallo #FrontendFriday-Leser/in, unstrukturierte Scripte sind schlecht zu warten und kollidieren mit anderen Skripten. ES6 bietet in diesem Zusammenhang zwei allgemein akzeptierte Vorschläge für die Lösung dieses Problems: AMD (Asynchronous Module Definition) und die Module-Definition aus CommonJS.

Doch was ist, wenn der IE noch unterstützt werden muss? Fakt ist, der IE unterstützt keine ES6-Module ohne einen JavaScript-Compiler, welcher modernes JavaScript in altes verwandelt. Doch gibt es auch eine alternative Lösung? Weiterlesen lohnt sich…

 

Als Webentwickler hat man heutzutage immer mehr mit umfangreichen Anwendungen zu tun, in denen die Logik über mehrere unstrukturierte JavaScript-Dateien verteilt ist. Dies können sowohl interne Skripte als auch Fremdbibliotheken sein. Auf die Variablen- und Funktionsnamen der letzteren Ausprägung hat man als Entwickler selbst keinen Einfluss. Folglich können schwer auffindbare Namenskonflikte entstehen, welche zwangsläufig zu einer gravierenden Unübersichtlichkeit führen und schlecht wartbar sind. In diesem Zusammenhang ist es sehr wichtig zu wissen, dass alle Variablen und Funktionen im globalen window-Objekt des Browsers gesammelt werden und manipulierbar sind. In Sprachen wie C# und Java wird dieses Verhalten über Features wie Packages und Namespaces unterbunden. Beides existiert in ES5 nicht! Wir sollten uns deshalb Gedanken darüber machen, wie sich Variablen, Objekte etc. strukturieren lassen.

 

Im Netz wird in diesem Zusammenhang das Emulieren von Namespaces durch das sogenannte Namespace-Entwurfsmuster empfohlen. Dieses Pattern fasst zusammengehörige Variablen und Funktionen, getreu dem Singleton-Entwurfsmuster, zusammen und dient als ein einfacher Container. Das sorgt für einen Grad an Struktur und ermöglicht die Flucht aus dem globalen Gültigkeitsbereich. Solange das entsprechende Objekt einen global eindeutigen Namen hat, führt dieses Vorgehen zu keinen Namenskonflikten. Einen entscheidenden Nachteil hat das Namespace-Entwurfsmuster. Es sind zwar die Probleme der Namenskonflikte gelöst, nicht aber, die der Sichtbarkeit von Variablen und Funktionen. Objekte sollten jedoch, getreu dem Motto Datenkapselung, nur so viel an Informationen nach außen hin preisgeben, wie unbedingt notwendig.

 

Das Revealing-Module-Entwurfsmuster, welches auf dem Namespace-Entwurfmuster basiert, löst das Problem der Datenkapselung durch die Verwendung von IIFE’s. Unter einer Immediately Invoked Function Expression versteht man eine Funktion, die nach der Deklaration direkt aufgerufen wird. Dabei findet die direkte Ausführung nur ein einziges Mal statt. Manche von euch wissen evtl. bereits worauf das Ganze hinaus läuft: Variablen, die in einer IIFE definiert werden, sind nur innerhalb der gesamten Funktion sichtbar. Das trifft im JavaScript im Prinzip auf alle Arten von Funktionen zu und wird als Function-Level-Scope bezeichnet. Um es genauer zu formulieren: IIFE’s ermöglichen das Emulieren von Block-Scopes. Ich spreche hier bewusst vom Emulieren, denn ES5 kennt keinen Block-Scope. Aber genug der Theorie, schauen wir uns mal ein Beispiel an.

 

Code-Beispiel

 

In unserem Beispiel emulieren wir ein Modul mit dem Namen JusticeLeague und einem eigenen privaten Sichtbarkeitsbereich. Unsere Implementierung hat dabei zwei Parameter. Die streng geheime sowie die öffentliche Namensliste von Superhelden. Im Kontext einer IIFE besteht die Möglichkeit ein Objekt zurückzugeben, das die öffentliche API darstellt und Methoden und Eigenschaften außerhalb unseres Moduls sichtbar macht. Die Methoden dieses öffentlichen Objekts haben Zugriff auf alle Eigenschaften und Funktionen des Moduls. In anderen Worten ausgedrückt, alle Eigenschaften und Methoden werden erstmal privat und im Rückgabeobjekt öffentlich gemacht. Ein wichtiger Punkt ist, dass die Methoden des Rückgabeobjekts keine Kopie, sondern lediglich eine Referenz auf die entsprechende Variable zurückgeben. Deswegen spricht man in diesem Zusammenhang ebenfalls vom Singleton. Schauen wir uns als nächstes den Beweis an.

 

window-Objekt mit Unterscope JusticeLeague

 

Das Beispiel zeigt einen Auszug aus einem window-Objekt einer beliebigen Stack-Overflow Seite. Nach der Ausführung unserer IIFE sehen wir, dass unser Modul in einem eigenen Unterscope definiert ist. Lediglich die Methode getName() ist dabei öffentlich zugänglich.

 

Superhero-Module Beispielaufruf

 

Nach der Ausführung der Methode ist zu sehen, dass die Liste der öffentlichen Namen „Superman“ und “Batman” zurückgegeben wird. Der Zugriff auf den streng geheimen Namen ist nicht möglich. Genial oder? Falls ihr übrigens ein anderes Modul, wie z.B. jQuery, in eurem Modul nutzen wollt, könnt ihr dieses als Parameter übergeben.

 

 

Folgend die Vorteile des Revealing-Module-Patterns nochmals zusammengefasst:

  • Strukturierung/Wartbarkeit/Übersichtlichkeit
  • Datenkapselung
  • Modularisierung
  • Unterstützung in sämtlichen Browsern ohne spezielle Compiler
  • Kombinierung mit anderen Entwurfsmustern ist spielend Möglich, z.B. dem State-Pattern

 

Zurück zur Übersicht

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*Pflichtfelder

*

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.