Kürzlich wurde ich in einem großen Webprojekt mit Namespaces in JavaScript konfrontiert. Kurz gesagt geht es darum, Funktionen abzugrenzen, damit keine Konflikte entstehen, wenn Bezeichner mehrfach verwendet werden. Hat beispielsweise der Entwickler für die UX-Animationen eine Funktion “initialize” genannt und der Entwickler für die Video-Integration hat eine Funktion gleichen Namens definiert, gibt es Konflikte. In Großprojekten wird es schnell unübersichtlich und hier helfen die JS-Namespaces.

Ich habe natürlich zunächst mal die große Suchmaschine befragt. Hier bekommt man auch einiges ausgespuckt – allerdings war es mir dann oft eine Spur zu tiefgreifend und eigentlich immer auf Englisch. Für einen schnellen und pragmatischen Ansatz musste ich mich durch ziemlich viele und ziemlich lange Artikel kämpfen. Wer dazu keine Zeit hat, findet meinen kleinen Artikel eventuell hilfreich. Für alle anderen kann ich folgende Links empfehlen:

https://medium.freecodecamp.com/javascript-modules-a-beginner-s-guide-783f7d7a5fcc#.seyyc8cn9

https://addyosmani.com/largescalejavascript/

Jetzt aber wie versprochen in die Praxis.

Eine gute Möglichkeit einen Namespace zu erstellen ist, ein Objekt mittels Funktion zu definieren. Das sieht wie folgt aus:

var namespace = (function() {
  ...
})();

Soweit, so billig erstmal. Jetzt brauchen wir aber auch Methoden innerhalb unseres Namespaces. Diese definieren wir ganz ähnlich:

var namespace = (function() {
  var test = function() {
    console.log('Funktioniert!');
  };
  return {
    test: test
  }
})();

Wichtig ist hierbei, dass als Rückgabewert die öffentliche Funktion definiert wird. Diese lässt sich nun aus dem Code heraus aufrufen, z.B. durch einen Mausklick auf einem HTML-Objekt:

<a href="#" onclick="namespace.test();">Klick mich</a>

Wichtig und interessant ist hier, dass die Funktion “test();” nur mit dem vorangestellten “namespace.” aufgerufen werden kann. Das verhindert, dass Funktionen mehrfach definiert und verwechselt werden.

Es lassen sich auch Funktionen definieren, die nur innerhalb des Namespaces aufgerufen werden können. Das erweiterte Beispiel sieht dann so aus:

var namespace = (function() {
  var test = function() {
    privatFunktion();
  };
  function privatFunktion() {
    console.log('Funktioniert!');
  }
  return {
    test: test
  }
})(); 

Von außen kann ich die Funktion “privatFunktion()” nicht ansprechen – wohl aber innerhalb meines Namespaces.

Nun ist es aber auch wichtig, etwas über die Gültigkeitsbereiche von Variablen zu wissen. Definiere ich im Beispiel eine Variable innerhalb meines Namespace, so ist sie logischerweise auch nur hier gülitg. Auf globale Variablen, die außerhalb des Namespace definiert wurden, kann ich selbstverständlich immer zugreifen.

var globalString = 'Mich gibt es überall.';
var namespace = (function() {
  var sTest = 'Funktioniert!';
  var test = function() {
    privatFunktion();
  };
  function privatFunktion() {
    console.log(sTest);
    console.log(globalString);
  }
  return {
    test: test
  }
})(); 

Was mir nun noch gefehlt hat, war die Möglichkeit, Variablen an Funktionen im Namespace zu übergeben. Das ist nun auch recht einfach erledigt:

var namespace = (function() {
  var sTest = 'Funktioniert!';
  var test = function(exTest) {
    privatFunktion();
    console.log(exTest);    
  };
  function privatFunktion() {
    console.log(sTest);
  }
  return {
    test: test
  }
})(); 

Die Funktion test kann nun mit Parameter aus dem HTML übergeben werden:

<a href="#" onclick="namespace.test('Guten Tag!');">Klick mich</a>

Mit diesen einfachen Handgriffen lässt sich ein großes Webprojekt schon ganz gut strukturieren – zumindest, was das JavaScripting betrifft! Ich hoffe, ich konnte damit einen guten Start geben. Für Korrekturen und Anregungen bin ich per Mail erreichbar und immer dankbar!