Frage Wie deklariere ich einen Namespace in JavaScript?


Wie erstelle ich einen Namespace in JavaScript, damit meine Objekte und Funktionen nicht durch andere gleichnamige Objekte und Funktionen überschrieben werden? Ich habe Folgendes benutzt:

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

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


919
2018-05-19 08:11


Ursprung


Antworten:


Ich mag das:

var yourNamespace = {

    foo: function() {
    },

    bar: function() {
    }
};

...

yourNamespace.foo();

713
2018-05-19 08:22



ich benutze Der Ansatz, der auf der Enterprise jQuery-Site gefunden wurde:

Im folgenden Beispiel wird erläutert, wie private und öffentliche Eigenschaften und Funktionen deklariert werden. Alles wird als selbst-ausfü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, würden Sie einfach gehen skillet.fry() oder skillet.ingredients.

Was wirklich cool ist, ist, dass Sie jetzt den Namespace mit der exakt gleichen 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 Streit

Der dritte, undefined Argument ist die Quelle der Wertvariablen undefined. Ich bin mir nicht sicher, ob es noch heute relevant ist, aber während der Arbeit mit älteren Browsern / JavaScript-Standards (ecmascript 5, javascript <1.8.5 ~ firefox 4), die global-scope-Variable undefined ist beschreibbar, damit jeder seinen Wert umschreiben kann. Das dritte Argument (wenn kein Wert übergeben wird) erstellt eine Variable namens undefined welches auf den Namespace / die Funktion beschränkt ist. Da beim Erstellen des Namensbereichs kein Wert übergeben wurde, wird standardmäßig der Wert verwendet undefined.


1015
2018-05-10 08:28



Eine andere Möglichkeit, dies zu tun, was ich für etwas weniger restriktiv halte als die Objekt-Literalform, ist dies:

var ns = new function() {

    var internalFunction = function() {

    };

    this.publicFunction = function() {

    };
};

Das obige ist ziemlich ähnlich das Modulmuster und Egal, ob Sie es wollen oder nichterlaubt es Ihnen, alle Ihre Funktionen als öffentlich zugänglich zu machen, während Sie die starre Struktur eines Objektliterals vermeiden.


334
2018-05-19 08:39



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

Ja. Beispielsweise:

var your_namespace = your_namespace || {};

dann kannst du haben

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

154
2018-05-26 11:34



Normalerweise baue ich es in einem Verschluss:

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 subtil verändert, seit ich dies schreibe, und ich finde jetzt, dass ich die Schließung so schreibe:

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 Implementierung einfacher zu verstehen. Stellen Sie sich die Rückgabeanweisung als öffentliche Schnittstelle zur Implementierung vor.


88
2018-05-20 20:07



Da Sie möglicherweise verschiedene JavaScript-Dateien schreiben und diese später in einer Anwendung kombinieren oder nicht kombinieren können, muss jeder in der Lage sein, das Namespace-Objekt wiederherzustellen oder zu erstellen, ohne die Arbeit anderer Dateien zu beeinträchtigen ...

Eine Datei könnte den Namespace verwenden namespace.namespace1:

namespace = window.namespace || {};
namespace.namespace1 = namespace.namespace1 || {};

namespace.namespace1.doSomeThing = function(){}

Eine andere Datei möchte möglicherweise den Namespace verwenden namespace.namespace2:

namespace = window.namespace || {};
namespace.namespace2 = namespace.namespace2 || {};

namespace.namespace2.doSomeThing = function(){}

Diese beiden Dateien können ohne Kollision zusammen oder getrennt leben.


55
2017-11-09 04:27



Hier ist, wie Stojan Stefanov es in seinem tut JavaScript-Muster Buch, das ich als sehr gut empfand (es zeigt auch, wie er Kommentare erstellt, die eine automatisch generierte API-Dokumentation ermöglichen und eine Methode zum Prototyp eines benutzerdefinierten Objekts hinzufügen):

/**
* My JavaScript application
*
* @module myapp
*/

/** @namespace Namespace for MYAPP classes and functions. */
var MYAPP = MYAPP || {};

/**
* A maths utility
* @namespace MYAPP
* @class math_stuff
*/
MYAPP.math_stuff = {

    /**
    * Sums two numbers
    *
    * @method sum
    * @param {Number} a First number
    * @param {Number} b Second number
    * @return {Number} Sum of the inputs
    */
    sum: function (a, b) {
        return a + b;
    },

    /**
    * Multiplies two numbers
    *
    * @method multi
    * @param {Number} a First number
    * @param {Number} b Second number
    * @return {Number} The inputs multiplied
    */
    multi: function (a, b) {
        return a * b;
    }
};

/**
* Constructs Person objects
* @class Person
* @constructor
* @namespace MYAPP
* @param {String} First name
* @param {String} Last name
*/
MYAPP.Person = function (first, last) {

    /**
    * First name of the Person
    * @property first_name
    * @type String
    */
    this.first_name = first;

    /**
    * Last name of the Person
    * @property last_name
    * @type String
    */
    this.last_name = last;
};

/**
* Return Person's full name
*
* @method getName
* @return {String} First name + last name
*/
MYAPP.Person.prototype.getName = function () {
    return this.first_name + ' ' + this.last_name;
};

46
2018-04-22 15:44



Ich benutze diesen Ansatz:

var myNamespace = {}
myNamespace._construct = function()
{
    var staticVariable = "This is available to all functions created here"

    function MyClass()
    {
       // Depending on the class, we may build all the classes here
       this.publicMethod = function()
       {
          //Do stuff
       }
    }

    // Alternatively, we may use a prototype.
    MyClass.prototype.altPublicMethod = function()
    {
        //Do stuff
    }

    function privateStuff()
    {
    }

    function publicStuff()
    {
       // Code that may call other public and private functions
    }

    // List of things to place publically
    this.publicStuff = publicStuff
    this.MyClass = MyClass
}
myNamespace._construct()

// The following may or may not be in another file
myNamespace.subName = {}
myNamespace.subName._construct = function()
{
   // Build namespace
}
myNamespace.subName._construct()

Externer Code kann dann sein:

var myClass = new myNamespace.MyClass();
var myOtherClass = new myNamepace.subName.SomeOtherClass();
myNamespace.subName.publicOtherStuff(someParameter);

32
2018-05-19 08:26