Я хочу создать глобальное пространство имен для своего приложения, и в том пространстве имен я хочу другие пространства имен:
Например.
Dashboard.Ajax.Post()
Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent();
Я также хочу разместить их в отдельные файлы:
Однако я попытался использовать этот метод, однако он не будет работать, потому что то же имя переменной используется для пространства имен в 2 отдельных местах. Кто-либо может предложить альтернативу?
Спасибо.
Вам просто нужно убедиться, что вы не наступаете на свой объект пространства имен, если он уже был создан. Примерно так будет работать:
(function() {
// private vars can go in here
Dashboard = Dashboard || {};
Dashboard.Ajax = {
Post: function() {
...
}
};
})();
И файл RetrieveContent
будет определен аналогично.
Функция Yahoo Namespace специально предназначена для решения этой проблемы.
Добавлено:
Доступен источник функции. Вы можете скопировать его в свой код, если хотите, изменить корень с YAHOO на что-то другое и т. Д.
Есть несколько библиотек, которые уже предлагают такую функциональность, если вы хотите использовать или изучить предварительно запеченный (то есть испытанный) раствор.
Самый простой и наиболее свободный от ошибок вариант - это, вероятно, jQuery.extend
с аргументом deep
, установленным в значение true. (Причина, по которой я говорю, что это без ошибок, не потому, что я думаю, что jQuery.extend
страдает меньшим количеством ошибок, чем любая другая библиотека, но потому, что он предлагает четкую возможность глубокого копирования атрибутов от отправителя к приемнику - что большинство других библиотек явно не предоставляют. Это предотвратит появление многих трудно диагностируемых ошибок в вашей программе позже, потому что вы использовали мелкую копию расширения
и теперь у вас есть функции, выполняющиеся в контекстах, в которых вы не ожидали, что они будут выполняться. (Однако, если вы знаете, как вы будете расширять базовую библиотеку при разработке своих методов, это не должно быть проблемой.)
Вы можете сделать что-то вроде этого ...
HTML-страница, используя библиотеку с пространством имен:
<html>
<head>
<title>javascript namespacing</title>
<script src="dashboard.js" type="text/javascript"></script>
<script src="ajax.js" type="text/javascript"></script>
<script src="retrieve_content.js" type="text/javascript"></script>
<script type="text/javascript">
alert(Dashboard.Ajax.Post());
alert(Dashboard.RetrieveContent.RefreshSalespersonPerformanceContent());
Dashboard.RetrieveContent.Settings.Timeout = 1500;
alert(Dashboard.RetrieveContent.Settings.Timeout);
</script>
</head>
<body>
whatever...
</body>
</html>
Dashboard.js:
(function(window, undefined){
var dashboard = {};
window.Dashboard = dashboard;
})(window);
Ajax.js:
(function(){
var ajax = {};
ajax.Post = function() { return "Posted!" };
window.Dashboard.Ajax = ajax
})();
Retrieve_Content.js:
(function(){
var retrieveContent = {};
retrieveContent.RefreshSalespersonPerformanceContent = function() {
return "content retrieved"
};
var _contentType;
var _timeout;
retrieveContent.Settings = {
"ContentType": function(contentType) { _contentType = contentType; },
"ContentType": function() { return _contentType; },
"Timeout": function(timeout) { _timeout = timeout; },
"Timeout": function() { return _timeout; }
};
window.Dashboard.RetrieveContent = retrieveContent;
})();
Dashboard.js действует как отправная точка для всех пространств имен под ним. Остальные определены в соответствующих файлах. В Retrieve_Content.js я добавил некоторые дополнительные свойства в разделе Настройки
, чтобы при необходимости дать представление о том, как это сделать.
Создав объект NS, вы должны иметь возможность добавлять к нему откуда угодно. Хотя вы можете попробовать var NS = NS || {};
, чтобы гарантировать, что объект NS существует и не перезаписан.
// NS is a global variable for a namespace for the app's code
var NS = NS || {};
NS.Obj = (function() {
// Private vars and methods always available to returned object via closure
var foo; // ...
// Methods in here are public
return {
method: function() {
}
};
}());
Я считаю, что образец модуля может оказаться прямо у вас на пути. Вот хорошая статья о различных шаблонах модулей.
http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth