Javascript best practice define variable (namespace) check еще не определена

Хотелось получить мнения от экспертов, я объявляю переменную, которая будет выступать в качестве пространства имен для кода JavaScript для моего приложения, но я хочу проверить, что она еще не определена.

этот код является кратким и "кажется" работать - по какой-то причине я должен избегать этого и вместо этого использовать проверку типа "undef"?

var MY_NAMESPACE = MY_NAMESPACE || {};

Спасибо

Ответ 1

Это стандартный способ сделать это. См. анализ Мэтта Снайдера функции YAHOO.namespace, которая использует эту же проверку (также для того, чтобы упростить создание пространств имен).

Матовый код, который он адаптировал из YUI для пространства имен вне объекта window вместо объекта YAHOO:

window.object_mes_namespace = function() {   
    var a = arguments,    
        o = window,   
        i = 0,   
        j = 0,   
        tok = null,   
        name = null;   

    // iterate on the arguments   
    for (i = 0; i < a.length; i = i + 1) {   
        tok = a[i].split(".");   

        // iterate on the object tokens   
        for (j = 0; j < tok.length; j = j + 1) {   
            name = tok[j];             
            o[name] = o[name] || {};   
            o = o[name];   
        }   
    }   

    return o;   
}  

Обратите внимание на строку o[name] = o[name] || {};, которая соответствует вашему примеру.

Ответ 2

Хотя то, что вы опубликовали, часто встречается, я лично не считаю, что это лучший способ сделать это.

  • MY_NAMESPACE может оцениваться как false по нескольким причинам, отличным от undefined - переменная действительно может быть определена, но должна быть 0 или false или пустая строка, и вы можете закончить замену этой значение.

  • MY_NAMESPACE может оценивать значение true по нескольким причинам, отличным от уже являющегося объектом, - это может быть ненулевое число или true или строка, и это приведет к тому, что ваш script будет молча fail, потому что добавление свойств к примитиву завершится с ошибкой.

Действительно, лучший способ зависит от вашей цели. Если вы не хотите загрязнять существующую переменную/пространство имен, вы должны выполнить проверку typeof и остановить, если эта переменная уже определена, но не объект:

if (typeof MY_NAMESPACE == 'undefined') {
  // create a new namespace
  MY_NAMESPACE = {};
}

if (typeof MY_NAMESPACE == 'object') {
  // go ahead
} else {
  // MY_NAMESPACE was already defined, but it is not an object
  // your script will fail if you continue, so do what you must and stop
}

Если ваш script должен работать, просто слепо создайте пространство имен без каких-либо проверок (конечно, я не рекомендую вам это делать).


Изменить: (в ответ на комментарий @jball, подумал, что я просто добавлю его здесь)

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

  • Если это пространство имен предназначено только для вашего собственного приложения, должно быть довольно просто выбрать имя, которое не используется ни одной из библиотек, которые вы используете.

Ответ 3

Это уже предпочтительный способ.

Но ваш оператор ничего не делает, если вы не пропустите MY_NAMESPACE в другую область, потому что MY_NAMESPACE есть MY_NAMESPACE.

Ответ 4

Мне нравится пример YUI и используйте его для всех моих приложений. В вашем случае вы переназначаете MY_NAMESPACE независимо от того, что не является огромной сделкой, но я предпочитаю избегать этого назначения, если это не необходимо.

if (typeof myNamespace == "undefined" || !myNamespace) {
    var myNamespace = {};
}