Есть ли "сжатый" способ сделать пространство имен в 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());