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 = {};
}