Пространство Имен Javascript-Несколько Уровней


В настоящее время я делаю следующее, чтобы дать моему коду javascript пространство имен:

(function(foo, $, undefined) {
    // function: showNoteDialog
    foo.showNoteDialog = function() {
       // ...
    }
}(window.foo = window.foo || {}, jQuery));

Что я предпочел бы вместо:

foo.showNoteDialog()

Должно иметь многоуровневое пространство имен:

foo.notes.showDialog()
foo.other.showDialog()

Возможно ли это? Как бы я это сделал?

5 7

5 ответов:

В JS нет пространств имен, но вы можете назначить объекты другим объектам, таким как

x = {};
x.y = {};
x.y.z = function() {};

Вот как я обычно это делаю:

var TopLevel = TopLevel || {}; //Exentd or Create top level namespace
TopLevel.FirstChild = TopLevel.FirstChild || {}; //Extend or Create a nested name inside TopLevel

Использование этого метода обеспечивает безопасность между файлами. Если TopLevel уже существует, вы назначите его переменной TopLevel, если нет, вы создадите пустой объект, который можно расширить.

Итак, предполагая, что вы хотите создать приложение, которое существует в пространстве имен приложений и расширяется в нескольких файлах, вы хотите, чтобы файлы выглядели так:

Файл 1 (библиотека):

var Application = Application || {};

Application.CoreFunctionality = Application.CoreFunctionality || {};
Application.CoreFunctionality.Function1 = function(){
  //this is a function
}//Function1

Файл 2 (библиотека):

var Application = Application || {};

Application.OtherFunctionality = Application.OtherFunctionality || {};
Application.OtherFunctionality.Function1 = function(){
  //this is a function that will not conflict with the first
}

Файл 3 (рабочий):

//call the functions (note you could also check for their existence first here)
Application.CoreFunctionality.Function1();
Application.OtherFunctionality.Function1();

Взгляните на пространство имен .js . Он позволяет объявлять вложенные пространства имен с помощью открытых и закрытых методов. Это хорошо, потому что позволяет вызывать любой метод внутри блока пространства имен без префикса-независимо от области видимости.

(function() {
  namespace("example.foo", bar);

  function foobar() { return "foobar"; };
  function bar() { return foobar(); };
}());

example.foo.bar(); // -> "foobar"

Я делаю это с помощью боба.JS framework :

bob.ns.setNs('myApp.myMethods', {
    method1: function() {
        console.log('This is method 1');
    },

    method2: function() {
        console.log('This is method 2');
    }
});
//call method1.
myApp.myMethods.method1();
//call method2.
myApp.myMethods.method2();

Автоматизация многоуровневого объявления пространств имен в javascript очень проста, как вы можете видеть:

var namespace = function(str, root) {
    var chunks = str.split('.');
    if(!root)
        root = window;
    var current = root;
    for(var i = 0; i < chunks.length; i++) {
        if (!current.hasOwnProperty(chunks[i]))
            current[chunks[i]] = {};
        current = current[chunks[i]];
    }
    return current;
};

// ----- USAGE ------

namespace('ivar.util.array');

ivar.util.array.foo = 'bar';
alert(ivar.util.array.foo);

namespace('string', ivar.util);

ivar.util.string.foo = 'baz';
alert(ivar.util.string.foo); 

Попробуйте: http://jsfiddle.net/stamat/Kb5xY/ Сообщение в блоге: http://stamat.wordpress.com/2013/04/12/javascript-elegant-namespace-declaration/