Мой код превратится в беспорядок, если я не начну использовать какую-то технику пространства имен. Я относительно новичок в программировании больших проектов javascript, но имею значительный опыт системного программирования на C++/java/python и т. д.
В основном я пытаюсь определить, какой метод является предпочтительным для создания пространств имен javascript, и каковы плюсы/минусы для каждого метода.
Например, я мог бы использовать любой из следующих трех методов:
var proj.lib.layout = {
"centreElem":
function (elem, W, H){
},
"getAbsolutePosition":
function (elem){
}
};
OR
var proj.lib.layout = {};
(function(){
var l = proj.lib.layout;
l.centreElem = function (elem, winW, winH){
..
}
l.getAbsolutePosition = function (elem){
..
}
})();
OR
var proj.lib.layout = new function(){
function centreElem(elem, W, H){
..
}
function getAbsolutePosition(elem){
..
}
this.centreElem = centreElem;
this.getAbsolutePosition = getAbsolutePosition;
} ();
Есть и другие способы сделать это слишком очевидно, но это были первые, которые я увидел и о которых подумал. Может ли кто-нибудь сказать, что есть "лучший" метод, или, по крайней мере, указать мне на некоторые плюсы и минусы, из которых я могу оценить, какой из них лучше для меня?
Ответ 1 · рейтинг 3 · Nick Husher
Обратите внимание, что вам нужно создать все промежуточные объекты, прежде чем вы сможете назначить такой подобъект:
window.one.two.three = {}; // fails
window.one = { two: { three: {} } };
Рассмотрите возможность написания метода пространства имен, чтобы вы могли унифицировать код пространства имен. Например:
window.proj = {};
// n - {String} - A string representing a namespace to create on proj
// returns an object you can assign values to
window.proj.namespace = function(n) { /* ... */ };
(function(NS) {
NS.myMethod = function() {};
NS.myOtherMethod = function() {};
NS.myProperty = "FOO";
})(proj.namespace('lib.layout'));
assert(proj.lib.layout.myProperty === "FOO");
Ответ 2 · рейтинг 1 · Justin
Мой предпочтительный метод состоит в том, чтобы иметь один объект (чье имя обычно короткое, 2-3 символа и все в верхнем регистре) в качестве моего пространства имен, в котором будут содержаться все другие объекты.
Показанный ниже метод (который наиболее точно соответствует вашему второму примеру) также показывает, как скрыть любые частные функции:
// In this example the namespace is "QP"
if (!QP) {
var QP = {};
};
// Define all objects inside an closure to allow "private" functions
(function() {
QP.examplePublicFunction = function() {
...
}
function examplePrivateFunction() {
...
}
})();
Этот метод используется рядом других библиотек JavaScript, например json2.js.
Я никогда не чувствовал необходимости подразделять свои пространства имен на подпространства имен.
Ответ 3 · Peter Lyons
В библиотеке Javascript Google Closure используется этот стиль (который не совсем похож на другие из ваших примеров)
goog.math.clamp = function(value, min, max) {
return Math.min(Math.max(value, min), max);
};
Я бы придерживался этого простого стиля. Не беспокойтесь о самовыполняющихся оболочках анонимных функций. Тот, что в вашем примере, на самом деле не делает ничего полезного.
Ответ 4 · Nicola Peluchetti
По сути, все три примера используют одну и ту же технику "пространства имен", то есть создают базовый объект (ваше пространство имен), а затем дополняют его своими функциями.
обычно корневое пространство имен пишется заглавными буквами:
if (typeof (MYAPP) == "undefined" || !MYAPP) {
var MYAPP= {}
};
Затем вы можете добавлять функциональные возможности к этому базовому объекту различными способами. В вашем коде вы показываете три из них, но каждый из них дает один и тот же результат, вы можете вызвать две эти функции:
proj.lib.layout.centreElem(elem, W, H);
proj.lib.layout. getAbsolutePosition(elem);