Jak zadeklarować przestrzeń nazw w JavaScript?

Jak utworzyć przestrzeń nazw w JavaScript, aby moje obiekty i funkcje nie zostały nadpisane przez inne obiekty i funkcje o tej samej nazwie? Użyłem:

if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
Czy jest na to sposób bardziej elegancki lub zwięzły?
Author: George Stocker, 2009-05-19

27 answers

Podoba mi się:

var yourNamespace = {

    foo: function() {
    },

    bar: function() {
    }
};

...

yourNamespace.foo();
 716
Author: dfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-30 19:25:49

Używam podejścia znalezionego na stronie Enterprise jQuery :

Oto ich przykład pokazujący, jak deklarować prywatne i publiczne właściwości i funkcje. Wszystko odbywa się jako samodzielna funkcja anonimowa.

(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 ));

Więc jeśli chcesz uzyskać dostęp do jednego z członków publicznych, po prostu idź skillet.fry() lub skillet.ingredients.

Naprawdę fajne jest to, że możesz teraz rozszerzyć przestrzeń nazw używając dokładnie tej samej składni.

//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 ));

The third undefined argument

Trzeci, undefined argument jest źródłem zmiennej o wartości undefined. Nie jestem pewien, czy to nadal aktualne, ale podczas pracy ze starszymi przeglądarkami / standardami JavaScript (ecmascript 5, javascript undefined jest zapisywalna, więc każdy może przepisać jej wartość. Trzeci argument (gdy nie przekazuje wartości) tworzy zmienną o nazwie undefined, która jest ograniczona do przestrzeni nazw / funkcji. Ponieważ żadna wartość nie została przekazana podczas tworzenia przestrzeń nazw, domyślnie jest to wartość undefined.

 1018
Author: Jaco Pretorius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-17 14:20:49

Innym sposobem, który uważam za nieco mniej restrykcyjny niż literalna forma obiektu, jest:

var ns = new function() {

    var internalFunction = function() {

    };

    this.publicFunction = function() {

    };
};

Powyższe jest podobne do wzorca modułówi czy ci się to podoba, czy nie, pozwala na ujawnienie wszystkich funkcji jako publicznych, unikając sztywnej struktury obiektu dosłownego.

 335
Author: Ionuț G. Stan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-14 08:23:33
Czy jest na to sposób bardziej elegancki lub zwięzły?
Tak. Na przykład:
var your_namespace = your_namespace || {};

Wtedy możesz mieć

var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg) 
{
    alert(arg);
};
with(your_namespace)
{
   Bar(Foo.toAlert);
}
 154
Author: Alex Pacurar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-20 16:52:06

Normalnie buduję go w zamknięciu:

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";
        }
    };
})();

Mój styl przez lata miał subtelną zmianę od czasu pisania tego, a teraz piszę zamknięcie w ten sposób:

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
    };
})();

W ten sposób uważam, że publiczne API i implementacja są łatwiejsze do zrozumienia. Pomyśl o deklaracji return jako o publicznym interfejsie do implementacji.

 88
Author: Brett Ryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:09:36

Ponieważ możesz pisać różne pliki JavaScript, a później łączyć je lub nie łączyć w aplikacji, każdy z nich musi być w stanie odzyskać lub zbudować obiekt przestrzeni nazw bez szkody dla pracy innych plików...

Jeden plik może używać przestrzeni nazw namespace.namespace1:

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

namespace.namespace1.doSomeThing = function(){}

Inny plik może chcieć użyć przestrzeni nazw namespace.namespace2:

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

namespace.namespace2.doSomeThing = function(){}

Te dwa pliki mogą żyć razem lub osobno bez kolizji.

 55
Author: Fentex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:03:34

Oto jak Stoyan Stefanov robi to w swoim Szablony JavaScript książka, która okazała się bardzo dobra (pokazuje również, jak robi komentarze, które pozwalają na automatyczne generowanie dokumentacji API i jak dodać metodę do prototypu niestandardowego obiektu): {]}

/**
* 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;
};
 47
Author: Ciaran Bruen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:13:48

Stosuję takie podejście:

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()

Zewnętrzny kod może być wtedy:

var myClass = new myNamespace.MyClass();
var myOtherClass = new myNamepace.subName.SomeOtherClass();
myNamespace.subName.publicOtherStuff(someParameter);
 32
Author: AnthonyWJones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 19:51:47

Jest to kontynuacja linku user106826 do przestrzeni nazw.js. Wygląda na to, że projekt przeniósł się do GitHub . Jest teraz smith / namespacedotjs .

Używam tego prostego JavaScript helpera dla mojego małego projektu i jak dotąd wydaje się być lekki, ale wystarczająco wszechstronny, aby obsłużyć przestrzeń nazw i Ładowanie modułów/klas. Byłoby wspaniale, gdyby pozwoliło mi to zaimportować pakiet do wybranej przeze mnie przestrzeni nazw, a nie tylko globalnej przestrzeni nazw... westchnienie, ale to poza tym o to chodzi.

Pozwala zadeklarować przestrzeń nazw, a następnie zdefiniować obiekty / Moduły w tej przestrzeni nazw:

Namespace('my.awesome.package');
my.awesome.package.WildClass = {};

Inną opcją jest zadeklarowanie przestrzeni nazw i jej zawartości jednocześnie:

Namespace('my.awesome.package', {
    SuperDuperClass: {
        saveTheDay: function() {
            alert('You are welcome.');
        }
    }
});

Więcej przykładów użycia znajdziesz w przykładzie.plik js w źródle .

 32
Author: Rudy Lattae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:02:08

Próbka:

var namespace = {};
namespace.module1 = (function(){

    var self = {};
    self.initialized = false;

    self.init = function(){
        setTimeout(self.onTimeout, 1000)
    };

    self.onTimeout = function(){
        alert('onTimeout')
        self.initialized = true;
    };

    self.init(); /* If it needs to auto-initialize, */
    /* You can also call 'namespace.module1.init();' from outside the module. */
    return self;
})()

Możesz opcjonalnie zadeklarować zmienną local, same, Jak self i przypisać local.onTimeout, Jeśli chcesz, aby była prywatna.

 29
Author: Jim Jose,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:15:45

Możesz zadeklarować prostą funkcję zapewniającą przestrzenie nazw.

function namespace(namespace) {
    var object = this, tokens = namespace.split("."), token;

    while (tokens.length > 0) {
        token = tokens.shift();

        if (typeof object[token] === "undefined") {
            object[token] = {};
        }

        object = object[token];
    }

    return object;
}

// Usage example
namespace("foo.bar").baz = "I'm a value!";
 13
Author: dnemoga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:14:11

I created przestrzeń nazw który jest inspirowany modułami Erlanga. Jest to bardzo funkcjonalne podejście, ale tak piszę mój kod JavaScript w dzisiejszych czasach.

Nadaje domknięciu globalną przestrzeń nazw i eksponuje zdefiniowane funkcje zestawu w tym domknięciu.

(function(){

  namespace("images", previous, next);
  // ^^ This creates or finds a root object, images, and binds the two functions to it.
  // It works even though those functions are not yet defined.

  function previous(){ ... }

  function next(){ ... }

  function find(){ ... } // A private function

})();
 9
Author: The Who,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 19:59:22

Jeśli potrzebujesz zakresu prywatnego:

var yourNamespace = (function() {

  //Private property
  var publicScope = {};

  //Private property
  var privateProperty = "aaa"; 

  //Public property
  publicScope.publicProperty = "bbb";

  //Public method
  publicScope.publicMethod = function() {
    this.privateMethod();
  };

  //Private method
  function privateMethod() {
    console.log(this.privateProperty);
  }

  //Return only the public parts
  return publicScope;
}());

yourNamespace.publicMethod();

Else if you won ' t ever use the private scope:

var yourNamespace = {};

yourNamespace.publicMethod = function() {
    // Do something...
};

yourNamespace.publicMethod2 = function() {
    // Do something...
};

yourNamespace.publicMethod();
 9
Author: JedatKinports,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-22 12:33:52

Używam następującej składni dla przestrzeni nazw.

var MYNamespace = MYNamespace|| {};

 MYNamespace.MyFirstClass = function (val) {
        this.value = val;
        this.getValue = function(){
                          return this.value;
                       };
    }

var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());

Jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/

 8
Author: Razan Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-04 22:45:03

Wzorzec modułu został pierwotnie zdefiniowany jako sposób zapewnienia zarówno prywatnej, jak i publicznej enkapsulacji dla klas w konwencjonalnej inżynierii oprogramowania.

Podczas pracy z modułem pattern, może okazać się przydatne zdefiniowanie prostego szablonu, którego używamy do rozpoczęcia pracy z nim. Oto jeden, który obejmuje odstępy między nazwami, zmienne publiczne i prywatne.

W JavaScript, wzorzec modułu jest używany do dalszej emulacji pojęcia klas w taki sposób, że jesteśmy w stanie zawierają zarówno publiczne / prywatne metody, jak i zmienne wewnątrz jednego obiektu, chroniąc w ten sposób poszczególne części przed globalnym zasięgiem. Skutkuje to zmniejszeniem prawdopodobieństwa, że nasze nazwy funkcji będą sprzeczne z innymi funkcjami zdefiniowanymi w dodatkowych skryptach na stronie.

var myNamespace = (function () {

  var myPrivateVar, myPrivateMethod;

  // A private counter variable
  myPrivateVar = 0;

  // A private function which logs any arguments
  myPrivateMethod = function( foo ) {
      console.log( foo );
  };

  return {

    // A public variable
    myPublicVar: "foo",

    // A public function utilizing privates
    myPublicFunction: function( bar ) {

      // Increment our private counter
      myPrivateVar++;

      // Call our private method using bar
      myPrivateMethod( bar );

    }
  };

})();

Zalety

Dlaczego wzór modułu jest dobrym wyborem? Na początek jest to dużo czystsze dla programistów wywodzących się z tła zorientowanego obiektowo niż idea true enkapsulacji, przynajmniej z punktu widzenia JavaScript.

Po Drugie, obsługuje prywatne dane - Tak więc, we wzorze modułu, publiczne części naszego kodu są w stanie dotknąć prywatnych części, jednak świat zewnętrzny nie jest w stanie dotknąć prywatnych części klasy.

Wady

Wadą wzorca modułu jest to, że ponieważ mamy różny dostęp zarówno do członków publicznych, jak i prywatnych, kiedy chcemy zmienić widoczność, musimy wprowadzić zmiany w każdym z nich miejsce.

Nie możemy również uzyskać dostępu do prywatnych członków w metodach dodanych do obiektu w późniejszym punkcie . To powiedziawszy, w wielu przypadkach wzór modułu jest nadal bardzo przydatny i gdy jest używany poprawnie, z pewnością ma potencjał, aby poprawić strukturę naszej aplikacji.

Wzór Modułu Odkrywczego

Teraz, gdy jesteśmy trochę bardziej zaznajomieni ze wzorem modułów, spójrzmy na nieco ulepszoną wersję-Christian Schemat modułu Heilmanna.

Schemat modułu ujawniającego pojawił się, gdy Heilmann był sfrustrowany faktem, że musiał powtórzyć nazwę głównego obiektu, gdy chcieliśmy wywołać jedną publiczną metodę z innej lub uzyskać dostęp do publicznych zmiennych.Nie podobał mu się również wymóg Module pattern dotyczący konieczności przełączenia się na dosłowną notację obiektową dla rzeczy, które chciał upublicznić.

Rezultatem jego wysiłków był zaktualizowany wzór, w którym po prostu zdefiniowaliśmy wszystkie nasze funkcje i zmienne w zakresie prywatnym i zwracają anonimowy obiekt ze wskaźnikami do funkcji prywatnej, którą chcieliśmy ujawnić jako publiczną.

Przykład użycia wzorca modułu odsłaniającego znajduje się poniżej

var myRevealingModule = (function () {

        var privateVar = "Ben Cherry",
            publicVar = "Hey there!";

        function privateFunction() {
            console.log( "Name:" + privateVar );
        }

        function publicSetName( strName ) {
            privateVar = strName;
        }

        function publicGetName() {
            privateFunction();
        }


        // Reveal public pointers to
        // private functions and properties

        return {
            setName: publicSetName,
            greeting: publicVar,
            getName: publicGetName
        };

    })();

myRevealingModule.setName( "Paul Kinlan" );

Zalety

Ten wzorzec pozwala na bardziej spójną składnię naszych skryptów. To również sprawia, że bardziej jasne na końcu modułu, które z naszych funkcji i zmiennych mogą być dostępne publicznie, co ułatwia czytelność.

Wady

Wadą tego wzorca jest to, że jeśli funkcja prywatna odnosi się do funkcji publicznej, to ta funkcja Publiczna nie może być nadpisana, jeśli łata jest konieczna. Dzieje się tak dlatego, że funkcja prywatna będzie nadal odnosić się do prywatnej implementacji, a wzorzec nie ma zastosowania do członków publicznych, tylko do funkcji.

Public object members, które odnoszą się do prywatnych zmiennych, również podlegają powyższej uwadze do zasady no-patch.

 8
Author: Divyanshu Rawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-05 15:01:22

Po przeniesieniu kilku moich bibliotek do różnych projektów i konieczności ciągłego zmieniania najwyższego poziomu (statycznie nazwanej) przestrzeni nazw, przełączyłem się na użycie tej małej (open source) funkcji pomocniczej do definiowania przestrzeni nazw.

global_namespace.Define('startpad.base', function(ns) {
    var Other = ns.Import('startpad.other');
    ....
});

Opis korzyści znajduje się w moim blogu . Możesz pobrać kod źródłowy tutaj .

Jedną z zalet, które naprawdę lubię, jest izolacja między modułami w odniesieniu do kolejności ładowania. Możesz odwołać się do zewnętrznego moduł przed załadowaniem. A odniesienie do obiektu, które otrzymasz, zostanie wypełnione, gdy kod będzie dostępny.

 7
Author: mckoss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-27 14:24:32

Jestem spóźniony 7 lat na imprezę, ale zrobiłem sporo pracy wokół tego 8 lat temu:

Ważne jest, aby móc łatwo i wydajnie tworzyć wiele zagnieżdżonych przestrzeni nazw, aby utrzymać złożoną aplikację internetową zorganizowaną i zarządzalną, przy jednoczesnym poszanowaniu JavaScript globalna przestrzeń nazw (zapobieganie zanieczyszczeniu przestrzeni nazw), a przy tym nie zatykanie żadnych istniejących obiektów w ścieżce przestrzeni nazw.

Z powyższego wynika, że to było moje rozwiązanie z roku 2008:

var namespace = function(name, separator, container){
  var ns = name.split(separator || '.'),
    o = container || window,
    i,
    len;
  for(i = 0, len = ns.length; i < len; i++){
    o = o[ns[i]] = o[ns[i]] || {};
  }
  return o;
};

To nie jest tworzenie przestrzeni nazw, ale zapewnia funkcję do tworzenia przestrzeni nazw.

To może być skondensowane do zminiaturyzowanej jednowarstwowej:

var namespace=function(c,f,b){var e=c.split(f||"."),g=b||window,d,a;for(d=0,a=e.length;d<a;d++){g=g[e[d]]=g[e[d]]||{}}return g};

Przykład użycia:

namespace("com.example.namespace");
com.example.namespace.test = function(){
  alert("In namespaced function.");
};

Lub, jako jedno stwierdzenie:

namespace("com.example.namespace").test = function(){
  alert("In namespaced function.");
};

Albo jest następnie wykonywane jako:

com.example.namespace.test();

Jeśli nie potrzebujesz wsparcia dla starszych przeglądarek, zaktualizowanej wersji:

const namespace = function(name, separator, container){
    var o = container || window;
    name.split(separator || '.').forEach(function(x){
        o = o[x] = o[x] || {};
    });
    return o;
};

Teraz, byłbym niechętny ujawnieniu namespace samej globalnej przestrzeni nazw. (Szkoda, że język podstawowy nie zapewnia tego dla nas!) Więc zazwyczaj sam używam tego w zamknięciu, np.:

(function(){
	const namespace = function(name, separator, container){
		var o = container || window;
		name.split(separator || '.').forEach(function(x){
			o = o[x] = o[x] || {};
		});
		return o;
	};
	const ns = namespace("com.ziesemer.myApp");
	
	// Optional:
	ns.namespace = ns;
	
	// Further extend, work with ns from here...
}());

console.log("\"com\":", com);

W większej aplikacji, to musi być zdefiniowane tylko raz na początku ładowania strony (dla aplikacji internetowych opartych na kliencie). Dodatkowe pliki mogą następnie ponownie użyć funkcji przestrzeni nazw, jeśli są przechowywane (dołączone jako "opcjonalne" w powyższym). W najgorszym przypadku, jeśli ta funkcja jest ponownie zadeklarowana kilka razy - to tylko kilka linijek kodu, a mniej, jeśli jest minifigurowana.

 7
Author: ziesemer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-28 12:41:13

Musisz sprawdzić Przestrzeń nazw.js Wynocha!

 5
Author: user106826,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 19:53:14

Mój ulubiony wzór stał się ostatnio taki:

var namespace = (function() {
  
  // expose to public
  return {
    a: internalA,
    c: internalC
  }

  // all private
  
  /**
   * Full JSDoc
   */
  function internalA() {
    // ...
  }
  
  /**
   * Full JSDoc
   */
  function internalB() {
    // ...
  }
  
  /**
   * Full JSDoc
   */
  function internalC() {
    // ...
  }
  
  /**
   * Full JSDoc
   */
  function internalD() {
    // ...
  }
  
})();

Oczywiście, return może być na końcu, ale jeśli podążają za nim tylko deklaracje funkcji, o wiele łatwiej jest sprawdzić, o co chodzi w przestrzeni nazw i jakie jest narażone API.

Wzorzec używania wyrażeń funkcji w takich przypadkach powoduje, że nie jest w stanie wiedzieć, jakie metody są narażone bez przechodzenia przez cały kod.

 3
Author: Nomaed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-20 17:43:13

Podoba mi się rozwiązanie Jaco Pretoriusa, ale chciałem uczynić słowo kluczowe "this" nieco bardziej użytecznym, wskazując je na obiekt module/namespace. Moja wersja patelni:

(function ($, undefined) {

    console.log(this);

}).call(window.myNamespace = window.myNamespace || {}, jQuery);
 2
Author: haxpanel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:16:57

Dość kontynuacja odpowiedzi Ionuț G. Stan, ale pokazując korzyści płynące z czytelnego kodu za pomocą var ClassFirst = this.ClassFirst = function() {...}, który wykorzystuje zakres zamykania JavaScript dla mniej zaśmiecania przestrzeni nazw dla klas w tej samej przestrzeni nazw.

var Namespace = new function() {
    var ClassFirst = this.ClassFirst = function() {
        this.abc = 123;
    }

    var ClassSecond = this.ClassSecond = function() {
        console.log("Cluttered way to access another class in namespace: ", new Namespace.ClassFirst().abc);
        console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
    }
}

var Namespace2 = new function() {
    var ClassFirst = this.ClassFirst = function() {
        this.abc = 666;
    }

    var ClassSecond = this.ClassSecond = function() {
        console.log("Cluttered way to access another class in namespace: ", new Namespace2.ClassFirst().abc);
        console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
    }
}

new Namespace.ClassSecond()
new Namespace2.ClassSecond()

Wyjście:

Cluttered way to access another class in namespace: 123
Nicer way to access a class in same namespace: 123
Cluttered way to access another class in namespace: 666
Nicer way to access a class in same namespace: 666
 1
Author: lama12345,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-13 04:31:36

Możemy go używać niezależnie w ten sposób:

var A = A|| {};
A.B = {};

A.B = {
    itemOne: null,
    itemTwo: null,
};

A.B.itemOne = function () {
    //..
}

A.B.itemTwo = function () {
    //..
}
 1
Author: ganesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:21:42

Myślę, że wszyscy używacie za dużo kodu na tak prosty problem. Nie musisz robić za to repo. Oto funkcja pojedynczej linii.

namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);

Spróbuj:

// --- definition ---
const namespace = namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);

// --- Use ----
let myNamespace = namespace("a.b.c");
myNamespace.MyClass = class MyClass {};

// --- see ----
console.log("a : ", a);
 1
Author: Yairopro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 08:20:19

Jeśli używasz Makefile możesz to zrobić.

// prelude.hjs
billy = new (
    function moduleWrapper () {
    const exports = this;

// postlude.hjs
return exports;
})();

// someinternalfile.js
function bob () { console.log('hi'); }
exports.bob = bob;

// clientfile.js
billy.bob();

I tak wolę używać pliku Makefile, gdy dojdę do około 1000 linii, ponieważ mogę skutecznie skomentować duże fragmenty kodu, usuwając pojedynczą linię w pliku makefile. Ułatwia manipulowanie rzeczami. Ponadto, dzięki tej technice przestrzeń nazw pojawia się tylko raz w preludium, więc łatwo ją zmienić i nie trzeba jej powtarzać w kodzie biblioteki.

Skrypt powłoki do tworzenia na żywo w przeglądarce, gdy użycie pliku makefile:

while (true); do make; sleep 1; done

Dodaj to jako zadanie make ' go 'i możesz ' make go', aby twój build był aktualizowany podczas kodowania.

 0
Author: Samuel Danielson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-15 16:37:18

Napisałem kolejną bibliotekę przestrzeni nazw, która działa nieco bardziej jak pakiety / jednostki w innych językach. Pozwala na utworzenie pakietu kodu JavaScript i odwołanie się do tego pakietu z innego kodu:

/ Align = "left" / js
Package("hello", [], function() {
  function greeting() {
    alert("Hello World!");
  }
  // Expose function greeting to other packages
  Export("greeting", greeting);
});

Przykład Pliku.js

Package("example", ["hello"], function(greeting) {
  // Greeting is available here
  greeting();  // Alerts: "Hello World!"
});

Na stronie musi znajdować się tylko drugi plik. Jego zależności (plik hello.js w tym przykładzie) zostanie automatycznie załadowany i użyte zostaną obiekty wyeksportowane z tych zależności aby wypełnić argumenty funkcji zwrotnej.

Pokrewny projekt znajdziesz w pakiety JS.

 0
Author: Stijn de Witt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:05:44

Moim nawykiem jest używanie funkcji myName () jako magazynu właściwości, a następnie var myname jako posiadacza "metody"...

Czy to jest wystarczająco uzasadnione, czy nie, pobij mnie! Cały czas polegam na logice PHP i wszystko po prostu działa. : D

function myObj() {
    this.prop1 = 1;
    this.prop2 = 2;
    this.prop3 = 'string';
}

var myObj = (
 (myObj instanceof Function !== false)
 ? Object.create({

     $props: new myObj(),
     fName1: function() { /* code..  */ },
     fName2: function() { /* code ...*/ }
 })
 : console.log('Object creation failed!')
);

if (this !== that) myObj.fName1(); else myObj.fName2();

Możesz również zrobić to w sposób "vice versa", aby sprawdzić przed utworzeniem obiektu, który jest znacznie lepszy :

function myObj() {
    this.prop1 = 1;
    this.prop2 = 2;
    this.prop3 = 'string';
}

var myObj = (
    (typeof(myObj) !== "function" || myObj instanceof Function === false)
    ? new Boolean()
    : Object.create({
        $props: new myObj(),
        init: function () { return; },
        fName1: function() { /* code..  */ },
        fName2: function() { /* code ...*/ }
    })
);

if (myObj instanceof Boolean) {
    Object.freeze(myObj);
    console.log('myObj failed!');
    debugger;
}
else
    myObj.init();

Odniesienie do tego: JavaScript: Tworzenie obiektu z Obiekt.Utwórz()

 0
Author: Spooky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-28 20:19:37

W JavaScript nie ma predefiniowanych metod do używania przestrzeni nazw. W JavaScript musimy tworzyć własne metody definiowania przestrzeni nazw. Oto procedura, którą stosujemy w technologiach Oodles.

Zarejestruj Przestrzeń nazw Poniżej znajduje się funkcja rejestrowania przestrzeni nazw

//Register NameSpaces Function
function registerNS(args){
 var nameSpaceParts = args.split(".");
 var root = window;

 for(var i=0; i < nameSpaceParts.length; i++)
 {
  if(typeof root[nameSpaceParts[i]] == "undefined")
   root[nameSpaceParts[i]] = new Object();

  root = root[nameSpaceParts[i]];
 }
}

Aby zarejestrować Przestrzeń nazw wystarczy wywołać powyższą funkcję z argumentem jako przestrzenią nazw oddzieloną '.' (kropka). Na Przykład Niech Nazwa Twojej aplikacji to oodles. Możesz utworzyć przestrzeń nazw za pomocą metoda następująca

registerNS("oodles.HomeUtilities");
registerNS("oodles.GlobalUtilities");
var $OHU = oodles.HomeUtilities;
var $OGU = oodles.GlobalUtilities;

Zasadniczo stworzy strukturę przestrzeni nazw, jak poniżej w backendzie:

var oodles = {
    "HomeUtilities": {},
    "GlobalUtilities": {}
};

W powyższej funkcji masz zarejestrowaną przestrzeń nazw o nazwach "oodles.HomeUtilities" i "oodles.GlobalUtilities". Aby wywołać te przestrzenie nazw tworzymy zmienną tj. var $OHU i var $OGU.

Te zmienne są niczym innym jak aliasem do inicjalizacji przestrzeni nazw. Teraz, gdy zadeklarujesz funkcję należącą do HomeUtilities, zadeklarujesz ją w następujący sposób:

$OHU.initialization = function(){
    //Your Code Here
};

Powyżej jest inicjalizacja nazwy funkcji i jest ona umieszczana w przestrzeni nazw $OHU. i wywołanie tej funkcji w dowolnym miejscu w plikach skryptu. Wystarczy użyć poniższego kodu.

$OHU.initialization();

Podobnie, z inną przestrzenią nazw.

Mam nadzieję, że to pomoże.
 0
Author: Saurabh tiwary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-17 20:13:16