Gibt es eine „prägnante“ Möglichkeit, Namensräume in JavaScript durchzuführen?

StackOverflow https://stackoverflow.com/questions/13021

  •  08-06-2019
  •  | 
  •  

Frage

Ich bin häufig auf Websites gestoßen, die ihr gesamtes JavaScript in ein gepackt haben namespace Struktur nach dem Motto:

namespaces = { com : { example: { example.com's data} }

Allerdings scheint die sichere Einrichtung im Vergleich zu anderen Namespace-Frameworks eine relativ große Menge an Code zu erfordern (definiert als > 2 Zeilen).Ich habe mich gefragt, ob jemand eine prägnante Möglichkeit kennt, dies zu tun?Gibt es außerdem eine relativ standardisierte/konsistente Möglichkeit, es zu strukturieren?Ist zum Beispiel die com Ist der Namespace direkt an das globale Objekt angehängt, oder ist er über ein Namespace-Objekt angehängt?

[Bearbeiten:Hoppla, offensichtlich {com = { ... } } würde nicht annähernd das erreichen, was ich beabsichtigt hatte, danke an Shog9 für den Hinweis.]

War es hilfreich?

Lösung

Javascript hat keine eigenständigen Namespaces.Es verfügt über Funktionen, die einen Bereich zum Auflösen von Namen bieten können, und über Objekte, die zu den benannten Daten beitragen können, auf die in einem bestimmten Bereich zugegriffen werden kann.

Hier ist Ihr Beispiel, korrigiert:

var namespaces = { com: { example: { /* example.com's data */ } } }

Dies ist eine Variable namespaces einem Objektliteral zugewiesen wird.Das Objekt enthält eine Eigenschaft: com, ein Objekt mit einer Eigenschaft: example, ein Objekt, das vermutlich etwas Interessantes enthalten würde.

Sie können also etwas eingeben wie namespaces.com.example.somePropertyOrFunctionOnExample und es wird alles funktionieren.Natürlich ist es auch lächerlich.Sie haben keinen hierarchischen Namespace, Sie haben ein Objekt, das ein Objekt enthält, das ein Objekt mit den Dingen enthält, die Ihnen wirklich wichtig sind.

var com_example_data = { /* example.com's data */ };

Das funktioniert genauso gut, ohne die sinnlose Hierarchie.

Jetzt, wenn Sie tatsächlich wollen Um eine Hierarchie aufzubauen, können Sie Folgendes versuchen:

com_example = com_example || {};
com_example.flags = com_example.flags || { active: false, restricted: true};

com_example.ops = com_example.ops || (function()
    {
       var launchCodes = "38925491753824"; // hidden / private
       return {
         activate: function() { /* ... */ },
         destroyTheWorld: function() { /* ... */ }
       };
    })();

...was meiner Meinung nach einigermaßen prägnant ist.

Andere Tipps

Hier war ein interessanter Artikel von Peter Michaux zum Thema Javascript-Namespace.Er diskutiert drei verschiedene Arten von Javascript-Namespaces:

  1. Präfix-Namensraum
  2. Namensraum für einzelne Objekte
  3. Namensraum für verschachtelte Objekte

Ich werde nicht plagiieren, was er hier gesagt hat, aber ich denke, sein Artikel ist sehr informativ.

Peter ging sogar so weit, darauf hinzuweisen, dass es bei einigen von ihnen Leistungsaspekte gibt.Ich denke, es wäre interessant, über dieses Thema zu sprechen, wenn man bedenkt, dass die neuen ECMAScript Harmony-Pläne die 4.0-Pläne für Namensraum und Paketierung aufgegeben haben.

Ich versuche, der Yahoo-Konvention zu folgen, ein einzelnes übergeordnetes Objekt im globalen Bereich zu erstellen, das alles enthält.

var FP = {};
FP.module = {};
FP.module.property = 'foo';

Um sicherzustellen, dass Sie kein vorhandenes Objekt überschreiben, sollten Sie Folgendes tun:

if(!window.NameSpace) {
    NameSpace = {};
}

oder

var NameSpace = window.NameSpace || {};

Auf diese Weise können Sie dies oben in jede Datei Ihrer Anwendung/Website einfügen, ohne sich Gedanken über das Überschreiben des Namespace-Objekts machen zu müssen.Außerdem könnten Sie so Unit-Tests für jede Datei einzeln schreiben.

Der YUI-Bibliothek Die Bibliothek verfügt über Code, der die Namensraumvergabe mithilfe einer Funktion verarbeitet, die Ihnen möglicherweise vorzuziehen ist.Andere Bibliotheken können dies möglicherweise auch tun.

Alternativ zu einem Punkt oder Unterstrich können Sie auch das Dollarzeichen verwenden:

var namespaces$com$example = "data"; 

Mir gefällt auch das (Quelle):

(function() {
    var a = 'Invisible outside of anonymous function';
    function invisibleOutside() {
    }

    function visibleOutside() {
    }
    window.visibleOutside = visibleOutside;

    var html = '--INSIDE Anonymous--';
    html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
    html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
    contentDiv.innerHTML = html + '<br/><br/>';
})();

var html = '--OUTSIDE Anonymous--';
html += '<br/> typeof invisibleOutside: ' + typeof invisibleOutside;
html += '<br/> typeof visibleOutside: ' + typeof visibleOutside;
contentDiv.innerHTML += html + '<br/>';​

Verwenden Sie ein Objektliteral und entweder das this Objekt oder der explizite Name, um den Namensraum basierend auf den Geschwistereigenschaften der lokalen Variablen, die die Funktion enthält, durchzuführen.Zum Beispiel:

var foo = { bar: function(){return this.name; }, name: "rodimus" }
var baz = { bar: function(){return this.name; }, name: "optimus" }

console.log(foo.bar());
console.log(baz.bar());

Oder ohne das Explizite name Eigentum:

var foo = { bar: function rodimus(){return this; } }
var baz = { bar: function optimus(){return this; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

Oder ohne zu verwenden this:

var foo = { bar: function rodimus(){return rodimus; } }
var baz = { bar: function optimus(){return optimus; } }

console.log(foo.bar.name);
console.log(baz.bar.name);

Benutzen Sie die RegExp oder Object Konstruktorfunktionen, um Namenseigenschaften zu Zählervariablen und anderen gebräuchlichen Namen hinzuzufügen, und verwenden Sie dann a hasOwnProperty Test zur Überprüfung:

 var foo = RegExp(/bar/);
 
/* Add property */
foo.name = "alpha";

document.body.innerHTML = String("<pre>" + ["name", "value", "namespace"] + "</pre>").replace(/,/g, "&#09;");

/* Check type */
if (foo.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["foo", String(foo.exec(foo)), foo.name] + "</pre>").replace(/,/g, "&#09;");
  }

/* Fallback to atomic value */
else 
  {
  foo = "baz";
  }

var counter = Object(1);

/* Add property */
counter.name = "beta";

if (counter.hasOwnProperty("name")) 
  {
  document.body.innerHTML += String("<pre>" + ["counter", Number(counter), counter.name] + "</pre>").replace(/,/g, "&#09;");
  } 
else 
  {
  /* Fallback to atomic value */
  counter = 0;
  }

Das DOM verwendet die folgende Konvention, um HTML- und SVG-Elementschnittstellendefinitionen zu benennen:

  • HTMLTitleElement
  • SVGTitleElement
  • SVGScriptElement
  • HTMLScriptElement

Der JavaScript-Kern verwendet Prototypen, um den Namespace zu erstellen toString Methode als einfache Form des Polymorphismus.

Verweise

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top