Я изучаю как можно больше о шаблоне модуля, предложенном блогом Yahoo YUI.
Я заметил, что YUI предлагает возможность создать новый пустой объект пространства имен, не перезаписывая существующее одно и то же имя:
YAHOO.namespace("myProject");
который затем можно вызвать и использовать с YAHOO.myProject
(Напоминание: если YAHOO.myProject
уже существует, он не перезаписывается)
Как я могу добиться аналогичного эффекта с помощью простого javascript и без использования YUI?
Пожалуйста, объясните с максимально возможной детализацией.
В полной статье блога YUI, где это делается, можно найти здесь.
Поскольку я изучаю и укрепляю свои знания и навыки javascript, я пытаюсь создать свою собственную библиотеку javascript (даже если мне никогда не понадобится ее использовать).
В вашем примере он может работать следующим образом:
if (!YAHOO.myProject) {
YAHOO.myProject = {};
}
YAHOO.myProject.whatever = true;
или используя собственное имя родительского модуля:
var myModule = myModule || {}; // make sure parent is defined without overwriting
if (!myModule.myProject) {
myModule.myProject = {};
}
myModule.myProject.whatever = true;
Или определите свою собственную функцию пространства имен:
function myNamespace(item) {
if (!myModule[item]) {
myModule[item] = {};
}
}
myNamespace("myProject");
myNamespace.myProject.whatever = true;
Q. Как создать пустой объект пространства имен без перезаписывания другого объекта с тем же именем?
Вы не можете. По определению одно и то же имя не может ссылаться как на ваш новый пустой объект, так и на существующий объект.
Если вы имеете в виду "Как я могу проверить создание пустого объекта пространства имен, только если он еще не существует, в противном случае я хочу добавить его в существующий", то вы просто выполните это:
if (!YAHOO.myProject)
YAHOO.myProject = {};
// or you may see this variation:
YAHOO.myProject = YAHOO.myProject || {};
Мне не нравится последний, но он часто используется для достижения того же эффекта, что и выражение plain if.
Чтобы этот общий принцип более подробно рассмотрел эту статью: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
ОБНОВЛЕНИЕ: В соответствии с документацией API YUI для YAHOO.namespace()
, метод "Возвращает указанное пространство имен и создает его, если его не существует" - что вы заметите гораздо менее двусмысленным, чем формулировка блога, который вы читали, и в значительной степени поддерживает то, что я уже сказал...
myProject
альтернативному имени?
Редактировать Просто понял, что я не отвечаю прямо на ваш вопрос. Сожалею! Однако, надеюсь, это поможет вам понять некоторые альтернативные методы.
Это метод, который я использую время от времени, например, когда я хочу добавить свойство или функцию один раз и не разрешать его перезаписывать позже.
var module = new function(){
var modules = {}; //internal module cache
return function(name, module){
//return all modules
if( !name ) return modules;
//return specific module
if( modules[name] ) return modules[name];
//return the module and store it
return modules[name] = module;
}
}
Итак, вы можете использовать его так:
//will store this since it doesn't exist
module('test', 'foo'); //Since 'test' doesn't exist on the internal 'modules' variable, it sets this property with the value of 'foo'
module('test'); // Since we aren't passing a 2nd parameter, it returns the value of 'test' on the internal 'modules' variable
module('test', 'bar'); //We are attempting to change the value of 'test' to 'bar', but since 'test' already equals 'foo', it returns 'foo' instead.
module(); // { 'test': 'foo' } //Here we aren't passing any parameters, so it just returns the entire internal 'modules' variable.
Ключевым моментом является то, что мы используем "new function()". Это делается при назначении, потому что мы действительно хотим, чтобы "модуль" был внутренней, а не внешней. Но для того, чтобы создать замыкание для внутренней переменной "var modules", внешняя функция должна выполняться при назначении.
Также обратите внимание, что вы также можете написать внешнюю функцию:
var module = function(){
var modules = {};
//other stuff
}();
module('test2', 'foo2');
в дополнение к тому, что у вас есть?
myModule.myProject
уже существует, не будет ли код, который вы только что написали, помешатьmyProject
объектаmyProject
?