Для определения модулей и констант приложения на JavaScript я люблю применять функцию аналогичную namespace
из библиотеки YUI3
. Она возвращает объект, который соответствует указанному пути или создает новый, если таковой не нашелся. Ценность этой функции в том, что можно не заботиться о том, что какая-то многоуровневая вложенность будет испорчена. Так же она позволяет определять поля в любом порядке.
На практике типовое использование этой функции сводится к получению (или созданию) объекта и тут же заполнению его какими-то полями. Я решил объединить эти действия в один вызов. Так как в этом случае не требуется объявлять несколько модулей, то этот функционал был удален вообще.
(function (window, undefined) {
var NS = "APP",
app = window[NS] = window[NS] || {};
/**
* Get or create namespace for module
* @param ns {String} namespace
* @param origin {Object} initial object (optional)
* @return {Object}
*/
app.namespace = app["namespace"] || function (ns, origin) {
var i, obj = window[NS], nsParts = ns.split('.');
for (i = (nsParts[0] === NS) ? 1 : 0; i < nsParts.length; i++) {
obj[nsParts[i]] = obj[nsParts[i]] || (i === nsParts.length - 1 && origin) || {};
obj = obj[nsParts[i]];
}
return obj;
};
}(window));
Такая функция должна быть объявлена одна из первых, т.к. задает namespace для всего приложения.
Её можно вызывать с одним строковым параметром
APP.namespace("APP.Module1");
или двумя параметрами — строковым и объектом, все поля которого будут перенесены в целевой namespace.
APP.namespace("APP.Module2", {
method1: function () {
},
FIELD: "test"
});
Для названий можно использовать укороченный синтаксис и опускать базовое имя. Так вызовы APP.namespace("Module1")
и APP.namespace("APP.Module1")
будут эквивалентны.
Такую функцию удобно переносить из проекта в проект. Достаточно поменять только значение константы NS.