2012-04-05 7 views
0

Ich versuche geschachtelte Klassendefinitionen in Javascript zu erstellen, um nur ein globales Objekt zu haben.geschachtelte Klassendefinition, ohne zusätzliche globale Objekte zu erstellen

Im Moment definieren wir neue Klassen wie folgt aus:

FOO.Navigation.Sidebar.Tooltip = function() 
{ 
}; 

So in jeder Funktionsdefinition müssen wir die ganze verschachtelte Klasse Namespace wiederholen:

FOO.Navigation.Sidebar.Tooltip.prototype.show = function() 
{ 
    /* do something here */ 
}; 

Wir einen Namespace-Funktion eingeführt zu erstellen die Klasse.

FOO = { /* ... */ } 

FOO.namespace = function(namespaceString) 
{ 
    var namespaceParts = namespaceString.split('.'); 
    var currentRoot = FOO; 
    var index = 0; 

    // Skip the first namespacePart, if it is already "FOO" 
    if ("FOO" == namespaceParts[0]) 
    { 
    index = 1; 
    } 

    var currentPart; 
    for(index; index < namespaceParts.length; index++) 
    {  
    // This is the next element in the namespace hierarchy. 
    currentPart = namespaceParts[index]; 
    // Add a new map for the currentPart to the root (if it does not exist yet). 
    currentRoot[currentPart] = currentRoot[currentPart] || {}; 
    // The currentPart will be the new root in the next loop. 
    currentRoot = currentRoot[currentPart]; 
    } 

    return currentRoot; 
}; 

Jetzt wollen wir diese verwenden, um eine besser lesbare Version der bisherigen Definitionen zu erstellen, die wie folgt aussehen:

FOO.Navigation.Sidebar.Tooltip = function() 
{ 
    this.hallo = "world"; 
}; 

var tooltip = FOO.Navigation.Sidebar.Tooltip; 

tooltip.prototype.show = function() 
{ 
    /* do something */ 
}; 

, dass eine neue globale Variable „Tooltip“ schaffen würde, und wir haben den Typ der Klassenname zweimal. So thougth wir anonyme Funktionen wie folgt zu verwenden:

(function(tooltip) { 
    tooltip = function() 
    { 
    this.hello = "world"; 
    }; 

    tooltip.prototype.show= function() 
    { 
    /* do something */ 
    }; 
}) (FOO.namespace("FOO.Navigation.Sidebar.Tooltip")) 

Das ist offensichtlich nicht funktionieren, weil wir eine neue Funktionsdefinition assing zu „Tooltip“.

Also meine Frage ist, ob es eine Möglichkeit gibt, den Klassennamen nur einmal zu schreiben, ohne weitere globale Variablen zu erstellen.

+0

Ich erinnere Sie daran, dass Sie JavaScript, nicht Java schreiben. All dies 'foo.bar.baz.trev.cat.mouse' Namespace Malarkey gehört nicht in JavaScript. – Matt

+0

Nun, wir versuchen, das Framework für unsere C++ - Entwickler zugänglicher zu machen. Deshalb versuchen wir zum Beispiel zusätzliche globale Variablen zu vermeiden. –

Antwort

0

Es sieht für mich aus, als ob Sie versuchen, eine Implementierung der Module Pattern zu erstellen. Module werden im Allgemeinen verwendet, um Einzelinstanzobjekte zu erstellen. Sie können jedoch einfach Factory-Methoden zum Modul hinzufügen, die neue Closures (Funktionen) zurückgeben.

Mit dem Code, den Sie oben eingefügt haben, können Sie Methoden direkt an die mitgelieferte Variable tooltip innerhalb des Verschlusses anhängen; zum Beispiel:

(function(Tooltip) { 
    // 'Static' method added to the module definition. 
    Tooltip.hello = function() { 
     alert("Hello!"); 
    }; 

    // Factory method which returns a new object. 
    Tooltip.create(message) { 
     return { 
      this.message = message; 
      this.show = function() { /* ... */ } 
     }; 
    } 
})(FOO.namespace("FOO.Navigation.Sidebar.Tooltip")); 

Dann können Sie die hello Methode auf Tooltip aufrufen:

// Invoke a static method. 
FOO.Navigation.Sidebar.Tooltip.hello();​ 

// Create a new ToolTip instance. 
var myToolTip = FOO.Navigation.Sidebar.Tooltip.create("Hello World"); 
myToolTip.show(); 

Wenn Sie eine hierarchische Klassenstruktur erstellen möchten, dann können Sie eine der gemeinsamen JavaScript-Bibliotheken zu prüfen, wie Backbone.js

+0

Ja, du hast Recht, aber was nicht so funktioniert, ist die Definition des Konstruktors. –

+0

Hallo Stefan, ich habe meine Antwort aktualisiert, um einen Verweis auf das Modulmuster hinzuzufügen und die Fabrikmethoden hinzuzufügen. Es klingt für mich, dass Sie besser von einem klassischeren OOP-Design bedient werden könnten (was einige sagen, dass es gegen die Sprache von JavaScript spricht). – JonnyReeves