1078 Stimmen

Wie deklariere ich einen Namespace in JavaScript?

Wie erstelle ich einen Namespace in JavaScript, damit meine Objekte und Funktionen nicht von anderen gleichnamigen Objekten und Funktionen überschrieben werden? Ich habe das Folgende verwendet:

if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}

Gibt es eine elegantere oder prägnantere Methode, dies zu tun?

21 Stimmen

Ich kann sehen, wo Sie mit der Überprüfung gehen, um zu sehen, wenn der Namespace genommen wird, aber da das Objekt nicht erstellt werden, wenn dies fehlschlägt, denke ich, der bessere Ansatz ist zu warnen, wenn der Namespace genommen wird. Offen gesagt sollte dies einfach nicht in den meisten JS-Situationen passieren und sollte schnell in der Entwicklung gefangen werden.

19 Stimmen

Nehmen Sie einen "Namespace" der obersten Ebene (Fenstereigenschaft). Besitzen Sie ihn. Konflikte sollten bereits in der Testphase erkannt werden. Machen Sie sich nicht die Mühe, all diese "Was wäre wenn"-Prüfungen hinzuzufügen. Es ist ein fatales Problem für doppelte "Namensräume" und sollte als solches behandelt werden . Sie können einen Ansatz wie jQuery verfolgen, um das Bewohnen eines benutzerdefinierten "Namespace" zu ermöglichen; aber dies ist immer noch eine Frage der Entwurfszeit.

0 Stimmen

Siehe auch stackoverflow.com/questions/2102591/ bei Leistungsproblemen

1076voto

Jaco Pretorius Punkte 24562

Ich benutze der Ansatz, der auf der Enterprise jQuery-Website zu finden ist :

Das folgende Beispiel zeigt, wie man private und öffentliche Eigenschaften und Funktionen deklariert. Alles wird als selbstausführende anonyme Funktion ausgeführt.

(function( skillet, $, undefined ) {
    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }
}( window.skillet = window.skillet || {}, jQuery ));

Wenn Sie also auf eines der öffentlichen Mitglieder zugreifen möchten, gehen Sie einfach auf skillet.fry() o skillet.ingredients .

Das Tolle daran ist, dass Sie den Namensraum jetzt mit genau derselben Syntax erweitern können.

//Adding new Functionality to the skillet
(function( skillet, $, undefined ) {
    //Private Property
    var amountOfGrease = "1 Cup";

    //Public Method
    skillet.toString = function() {
        console.log( skillet.quantity + " " +
                     skillet.ingredient + " & " +
                     amountOfGrease + " of Grease" );
        console.log( isHot ? "Hot" : "Cold" );
    };
}( window.skillet = window.skillet || {}, jQuery ));

Der dritte undefined Argument

Der dritte, undefined ist die Quelle der Variablen mit dem Wert undefined . Ich bin mir nicht sicher, ob es heute noch relevant ist, aber bei der Arbeit mit älteren Browsern / JavaScript-Standards (ecmascript 5, javascript < 1.8.5 ~ firefox 4), die global-scope Variable undefined ist beschreibbar, so dass jeder seinen Wert umschreiben kann. Das dritte Argument (wenn kein Wert übergeben wird) erzeugt eine Variable namens undefined die auf den Namensraum/die Funktion skaliert ist. Da bei der Erstellung des Namensraums kein Wert übergeben wurde, wird standardmäßig der Wert undefined .

814voto

dfa Punkte 110809

Das gefällt mir:

var yourNamespace = {

    foo: function() {
    },

    bar: function() {
    }
};

...

yourNamespace.foo();

357voto

Ionuț G. Stan Punkte 168218

Eine andere Möglichkeit, die ich für etwas weniger restriktiv halte als die objektwörtliche Form, ist diese:

var ns = new function() {

    var internalFunction = function() {

    };

    this.publicFunction = function() {

    };
};

Die obigen Ausführungen entsprechen in etwa das Modulmuster y ob es Ihnen gefällt oder nicht ermöglicht es Ihnen, alle Ihre Funktionen als öffentlich darzustellen und dabei die starre Struktur eines Objektliterales zu vermeiden.

161voto

Alex Pacurar Punkte 5713

Gibt es eine elegantere oder prägnantere Möglichkeit, dies zu tun?

Ja. Zum Beispiel:

var your_namespace = your_namespace || {};

dann können Sie

var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg) 
{
    alert(arg);
};
with(your_namespace)
{
   Bar(Foo.toAlert);
}

97voto

Brett Ryan Punkte 24930

Normalerweise baue ich sie in einen Verschluss ein:

var MYNS = MYNS || {};

MYNS.subns = (function() {

    function privateMethod() {
        // Do private stuff, or build internal.
        return "Message";
    }

    return {
        someProperty: 'prop value',
        publicMethod: function() {
            return privateMethod() + " stuff";
        }
    };
})();

Mein Stil hat sich im Laufe der Jahre, seit ich dies geschrieben habe, leicht verändert, und ich schreibe den Schluss jetzt so:

var MYNS = MYNS || {};

MYNS.subns = (function() {
    var internalState = "Message";

    var privateMethod = function() {
        // Do private stuff, or build internal.
        return internalState;
    };
    var publicMethod = function() {
        return privateMethod() + " stuff";
    };

    return {
        someProperty: 'prop value',
        publicMethod: publicMethod
    };
})();

Auf diese Weise finde ich die öffentliche API und die Implementierung leichter zu verstehen. Betrachten Sie die return-Anweisung als öffentliche Schnittstelle zur Implementierung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X