Есть ли "сжатый" способ сделать пространство имен в JavaScript?

Я часто сталкивался с сайтами, которые помещали все их javascript в структуру "пространства имен" вдоль строк

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

Но для безопасной установки в отношении других фреймворков с именами, по-видимому, требуется относительно большой объем кода (определяется как > 2 строки). Мне было интересно, знает ли кто-нибудь о сжатом способе сделать это? и существует ли относительно стандартный/последовательный способ его структурирования? например. - это пространство имен "com", непосредственно привязанное к глобальному объекту или прикрепленное через объект пространства имен?

[Edit: whoops, очевидно, {com = { ... } } не выполнит ничего близкого к тому, что я намеревался, благодаря Shog9 для указания этого.: D]

Ответы

Ответ 1

Javascript не имеет автономных пространств имен. Он имеет функции, которые могут предоставить возможности для разрешения имен и объектов, которые могут вносить вклад в именованные данные, доступные в данной области.

Вот ваш пример, исправлено:

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

Это переменная namespaces, которой присваивается литерал объекта. Объект содержит одно свойство: com, объект с одним свойством: example, объект, который предположительно будет содержать что-то интересное.

Итак, вы можете ввести что-то вроде namespaces.com.example.somePropertyOrFunctionOnExample, и все будет работать. Конечно, это тоже смешно. У вас нет иерархического пространства имен, у вас есть объект, содержащий объект, содержащий объект с материалом, который вам действительно нужен.

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

Это работает так же хорошо, без бессмысленной иерархии.

Теперь, если вы действительно хотите создать иерархию, вы можете попробовать что-то вроде этого:

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() { /* ... */ }
       };
    })();

... который, IMHO, достаточно краток.

Ответ 2

Вот интересная статья Петра Михо о Javascript Namespacing. Он обсуждает 3 разных типа пространства имен Javascript:

  • Префикс Namespacing
  • Очередность имен объектов
  • Вложенные имена имен объектов

Я не буду плагиатом, что он сказал здесь, но я думаю, что его статья очень информативна.

Питер даже зашел так далеко, чтобы указать, что с некоторыми из них есть соображения производительности. Я думаю, что этой теме было бы интересно поговорить о том, что новые планы ECMAScript Harmony отбросили планы 4.0 для размещения имен и упаковки.

Ответ 3

Я пытаюсь следовать соглашению Yahoo о том, чтобы исключить один родительский объект в глобальной области, чтобы содержать все;

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

Ответ 4

Чтобы убедиться, что вы не перезаписываете существующий объект, вам нужно что-то вроде:

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

или

var NameSpace = window.NameSpace || {};

Таким образом вы можете поместить это вверху каждого файла в своем приложении/веб-сайте, не беспокоясь о перезаписывании объекта пространства имен. Кроме того, это позволит вам писать отдельные тесты для каждого файла отдельно.

Ответ 5

Библиотека библиотека YUI имеет код, который обрабатывает пространство имен с помощью функции, которая может оказаться предпочтительной. Другие библиотеки тоже могут это сделать.

Ответ 6

В качестве альтернативы точке или подчеркиванию вы можете использовать знак знака доллара:

var namespaces$com$example = "data"; 

Ответ 7

Мне тоже нравится (источник):

(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/>';​

Ответ 8

Используйте литерал объекта и либо объект this, либо явное имя для размещения имен на основе свойств sibling локальной переменной, которая содержит эту функцию. Например:

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