Как я могу создать пустой объект пространства имен без перезаписи другого объекта с тем же именем?

1

Я изучаю как можно больше о шаблоне модуля, предложенном блогом Yahoo YUI.

Я заметил, что YUI предлагает возможность создать новый пустой объект пространства имен, не перезаписывая существующее одно и то же имя:

YAHOO.namespace("myProject");

который затем можно вызвать и использовать с YAHOO.myProject

(Напоминание: если YAHOO.myProject уже существует, он не перезаписывается)

Как я могу добиться аналогичного эффекта с помощью простого javascript и без использования YUI?

Пожалуйста, объясните с максимально возможной детализацией.

В полной статье блога YUI, где это делается, можно найти здесь.

Поскольку я изучаю и укрепляю свои знания и навыки javascript, я пытаюсь создать свою собственную библиотеку javascript (даже если мне никогда не понадобится ее использовать).

Теги:
namespaces
methods
javascript-namespaces
yui

3 ответа

2
Лучший ответ

В вашем примере он может работать следующим образом:

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;
  • 0
    Хорошо, но если myModule.myProject уже существует, не будет ли код, который вы только что написали, помешать myProject объекта myProject ?
  • 0
    @Proud_to_be_Noob - Точка инициализации пространства имен состоит в том, чтобы инициализировать его, если он еще не существует, и оставить его в покое, если он существует. Это то, что делает этот код. Вы пытаетесь сделать что-то еще?
Показать ещё 4 комментария
1

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(), метод "Возвращает указанное пространство имен и создает его, если его не существует" - что вы заметите гораздо менее двусмысленным, чем формулировка блога, который вы читали, и в значительной степени поддерживает то, что я уже сказал...

  • 0
    Я понимаю все, что вы только что сказали, и это именно то, о чем я думал раньше, так почему же блог YAHOO YUI утверждает: «Это назначает пустой объект myProject членом YAHOO (но не перезаписывает myProject, если он уже существует). Теперь мы можем начать добавлять членов в YAHOO.myProject. " YUI как-то автоматически переназначает дубликат myProject альтернативному имени?
1

Редактировать Просто понял, что я не отвечаю прямо на ваш вопрос. Сожалею! Однако, надеюсь, это поможет вам понять некоторые альтернативные методы.

Это метод, который я использую время от времени, например, когда я хочу добавить свойство или функцию один раз и не разрешать его перезаписывать позже.

    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
}();
  • 0
    Не могли бы вы добавить еще несколько комментариев во второй раздел, где вы покажете, как его использовать. Я понимаю первую часть, я просто хочу убедиться, что я понимаю вторую часть. Что происходит в коде - во втором разделе - если вы добавляете module('test2', 'foo2'); в дополнение к тому, что у вас есть?
  • 0
    Затем он добавит новое свойство к объекту внутренних модулей с именем 'test2': 'foo2'. В основном это позволяет вам установить свойства один раз, не имея возможности изменить их позже.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню