Objekte und Namespace Was meint Namespacing?

Zur Vermeidung von Namenskonflikten und aus Sicherheitsgründen sollten globale Objekte, die systemweit verwendet werden können, sparsam reserviert werden.

Direkte Objektzuordnung (Direct Assignment) Beispiel 1

Das folgende Objekt obj1 hat eine Anzahl obj1.anz, ein HTML-Objekt obj1.div und die Funktioen obj1.reset(), obj1.add(), obj1.show()

Für den Zugriff auf ein HTML-DOM-Objekt muß das globale window-Element mit window.document vorhanden sein.

Code Snippet: Direct Assignment
  1. <script>
  2. var obj1 = {
  3.     anz: 0,
  4.     div: function () {
  5.       return window.document.getElementById("SPAN1");
  6.     }
  7. };
  8. obj1.reset = function () { obj1.anz = 0; };
  9. obj1.add = function (x) { x = x || 1; obj1.anz += x; };
  10. obj1.show = function () { obj1.div().innerHTML = obj1.anz; };
  11. </script>
  12.  
  13. <a href="javascript:obj1.reset()"> reset() </a> |
  14.    <a href="javascript:obj1.add()"  >add() </a> |
  15.   <a href="javascript:obj1.show()" >show() </a> ==&gt; <span id="SPAN1"></span>

Teste: reset() | add() | show() ==>

Object Literal Notation Beispiel 2

Das folgende Beispiel gleicht dem vorherigen. Objektintern wird aber anstelle von
obj1.anz, obj1.add, obj1.show auch
this.anz, this.add, this.show verwendet. Im Objekt obj2 wird intern die this-Referenz verwendet. Dadurch erscheint der Objekt-Name (namespace-Bezeichner) lediglich einmal und kann bei Anpassungen an Bibliotheken leicht geändert werden. Aber bei der Verwendung der this-Referenz sind u.U. schwer durchschaubare (destruktive) Code-Manipulationen möglich.

Code Snippet: Object Literal Notation
  1. <script>
  2. var obj2 = {
  3.     anz: 0,
  4.     div: function () {
  5.       return window.document.getElementById("SPAN2");
  6.     },
  7.     reset: function () {
  8.       this.anz = 0; //obj2.anz = 0;
  9.     },
  10.     add: function (x) {
  11.       x = x || 1; this.anz += x; //obj2.anz += x;
  12.     },
  13.     show: function () {
  14.       this.div().innerHTML = this.anz; //obj2.div().innerHTML = obj2.anz;
  15.     }
  16. };
  17. </script>
  18.  
  19. <a href="javascript:obj2.reset()"> reset() </a> |
  20.    <a href="javascript:obj2.add()"  >add() </a> |
  21.   <a href="javascript:obj2.show()" >show() </a> ==&gt; <span id="SPAN2"></span>

Teste: reset() | add() | show() ==>

Module Pattern Beispiel 3

Das nachfolgende Muster verwendet. eine "anonym-kapselnde" Funktion (function wrapper), die bei der Ausgeführung ein Objekt obj3 erstellt und dieses zurück gibt. Typischwerweise wird das Objekt während dem Laden der Seite erstellt. Der Funktionsbereich der Wrapper-Funktion entspricht dem Sichtbarkeitsbereich der inneren Variablen. Dadurch sind alle Variablen, die nicht im return-Objekt definiert werden funktionsintern, d.h. privat.

Code Snippet: Module Pattern
  1. <script>
  2. var obj3 = (function () { // privat sind anz, div
  3.     var anz = 0,
  4.         div = function () {
  5.           return window.document.getElementById("SPAN3");
  6.         };
  7.  
  8.     return { // public sind reset, add, show
  9.       reset: function () {
  10.         anz = 0;
  11.       },
  12.       add: function (x) {
  13.         x = x || 1; anz += x;
  14.       },
  15.       show: function () {
  16.         div().innerHTML = anz;
  17.       }
  18.     }; // ende return
  19.  
  20. } ());
  21. </script>

Teste: reset() | add() | show() ==>

Namespace Argument Beispiel 4

Nachfolgend wird beim Aufruf der anonymen Wrapper-Funktion mit o = obj4 der gewünschte Namespace (Objektname) übergeben. Die inneren Variablen anz und win sind privat.

Globale ( an window gebundene) Funktionen reset(), add(), show() werden z.B. infolge der Parameter (window,window), d.h. infolge von (function (win, o) { ... })(window,window); erstellt.

Code Snippet
  1. <script>
  2.   var obj4 = {};
  3.  
  4.   (function (win, o) { // privat sind anz und win
  5.     var anz = 0,
  6.      div = function () {
  7.        return win.document.getElementById("SPAN4");
  8.      };
  9.     o.reset = function ( ) { anz = 0; };
  10.     o.add   = function (x) { x = x || 1; anz += x; };
  11.     o.show  = function ( ) { div().innerHTML = anz; };
  12.   })(window, obj4);
  13.  
  14. </script>
  15.  
  16. <a href="javascript:obj4.reset()"> reset() </a> |
  17.    <a href="javascript:obj4.add()"  >add() </a> |
  18.   <a href="javascript:obj4.show()" >show() </a> ==&gt; <span id="SPAN4"></span>

Teste: reset() | add() | show() ==>

Namespace Proxy (.apply) Beispiel 5

Im folgenden werden die Aufrufwerte this und ein Argument-Array an die anonyme Funktion mit Hilfe von .apply(obj5, [window]) übergeben. Der Namespace wird über das Schlüsselwort this gebunden.

Der Zugriff auf die Arrayelemente des Applay-Aufrufparameters erfolgt innerhalb der Funktion mit arguments .

Code Snippet: Namespace Proxy (.apply)
  1. <script>
  2.   var obj5 = {};
  3.  
  4.   (function () { // privat sind anz, arguments
  5.     var anz = 0, win = arguments[0],
  6.       div = function () {
  7.         return win.document.getElementById("SPAN5");
  8.       };
  9.     this.reset = function ( ) { anz = 0; };
  10.     this.add   = function (x) { x = x || 1; anz += x; };
  11.     this.show  = function ( ) { div().innerHTML = anz; };
  12.   }.apply(obj5, [window]));
  13.  
  14. </script>
  15.  
  16. <a href="javascript:obj5.reset()"> reset() </a> |
  17.    <a href="javascript:obj5.add()"  >add() </a> |
  18.   <a href="javascript:obj5.show()" >show() </a> ==&gt; <span id="SPAN5"></span>

Teste: reset() | add() | show() ==>

Kontex und Argument-Separation (.call) Beispiel 6

Im folgenden wird erzeugt ein call-Aufruf (User-Object, id-String, window-Referenz) von build.call() der Erzeugung eines User-Objektes.

Infolge des Aufrufes build.call(obj6, 'SPAN6', this); wird in der build-Funktion this durch obj6, id durch 'SPAN6' und win durch window ersetzt.

Code Snippet: Kontex und Argument-Separation (.call)
  1. <script>
  2.   var obj6 = {},
  3.       obj7 = {};
  4.  
  5.   var build = function (id, win) { // privat sind anz, id, win, div
  6.     var anz = 0,
  7.         div = function () {
  8.           return win.document.getElementById(id);
  9.         };
  10.     this.reset = function ( ) { anz = 0; };
  11.     this.add   = function (x) { x = x || 1; anz += x; };
  12.     this.show  = function ( ) { div().innerHTML = anz; };
  13.   };
  14.  
  15.   build.call(obj6, 'SPAN6', this);
  16.   build.call(obj7, 'SPAN7', this);
  17. </script>
  18. <a href="javascript:obj6.reset()"> obj6.reset() </a> |
  19.   <a href="javascript:obj6.add()"> obj6.add() </a> |
  20. <a href="javascript:obj6.show()" > obj6.show() </a> ==&gt; <span id="SPAN6"></span><br />
  21. <a href="javascript:obj7.reset()"> obj7.reset() </a> |
  22.   <a href="javascript:obj7.add()"> obj7.add() </a> |
  23. <a href="javascript:obj7.show()" > obj7.show() </a> ==&gt; <span id="SPAN7"></span>

Teste: obj6.reset() | obj6.add() | obj6.show() ==>
Teste: obj7.reset() | obj7.add() | obj7.show() ==>