#javascript #jquery
#javascript #jquery
Вопрос:
У меня есть следующий плагин:
(function($) {
$.fn.myPlugin = function(options) {
var opt = $.extend({}, $.fn.myPlugin.defaults, options);
if (!opt.a) {
console.log('a is required!');
return false;
}
if (!opt.b) {
console.log('b is required!');
return false;
}
if (!opt.c) {
console.log('c is required!');
return false;
}
//Rest of the logic
}
$.fn.myPlugin.defaults = {
};
});
Теперь этот плагин будет вызываться извне следующим образом:
$('div.x').myPlugin({
a:'aa',
b:'bb',
c:'cc'
});
Как вы можете видеть из плагина, мне нужны параметры a, b и c извне, т. е. они обязательны. Но там может быть 10-15 обязательных опций и этот код
if (!opt.a) {
console.log('a is required!');
return false;
}
if (!opt.b) {
console.log('b is required!');
return false;
}
if (!opt.c) {
console.log('c is required!');
return false;
}
может стать длинным и громоздким. Есть ли какой-нибудь более короткий или разумный способ написать это? Я думал о каком-нибудь общем коде.
Ответ №1:
Если их так много, вы могли бы поместить их в массив и проверить таким образом:
var required = ['a', 'b', 'c'];
var index, optname;
for (index = 0; index < required.length; index) {
optname = required[index];
if (!(optname in opt)) {
console.log(optname " is required");
return false;
}
}
Обратите внимание, что я сделал if (!(optname in opt))
проверку там (а не if (!opt[optname])
как у вас изначально было), чтобы разрешить параметры, которые должны быть указаны, но для которых допустимы 0
, false
, undefined
или другие ложные значения. in
Проверка проверяет, присутствует ли опция, не беспокоясь о том, что ее значение соответствует действительности.
Немного не по теме: вы можете предпочесть дождаться сбоя, пока не проверите все свойства, как указывает @Marcus в комментариях. Кроме того, вы могли бы рассмотреть возможность создания исключения, а не возврата false , поскольку тот, кто не смог правильно указать параметры, должен быть исключительным условием… Но это второстепенные моменты.
Комментарии:
1. @McStretch: Учился печатать в средней школе. 😉
2. Вот принятое мной решение, которое очень похоже на решение T.J. Я бы предпочел не
return false
до завершения цикла, чтобы убедиться, что все отсутствующие параметры указаны. К сожалению, мой ответ был удален (?!) до того, как у меня нашлось время его добавить, но я подумал, что поделюсь им здесь.3. @Marcus: Может быть, вы не опубликовали свой ответ в первую очередь / произошла ошибка при его публикации? На моем уровне репутации я могу видеть удаленные ответы (включая ответы, удаленные модераторами), и я не вижу ни одного от вас.
4. @T.J. О. Кажется, это был дублирующий вопрос, который создатель удалил 😉
5. @T.J.Crowder да, я дважды проверил и понял, что
in
работает по-разному вfor
иif
.
Ответ №2:
$.each(['a','b','c'], function(key, val) {
if (!opt[val] !== void 0) console.log(val " is require");
});
$.each
Просто намного короче / аккуратнее.
Хотя это то же самое, что и ответ @T.J.Crowder .
P.S. void 0 === undefined
Комментарии:
1. У вас должен быть флаг, говорящий о возврате false после
each
цикла (или генерировании исключения).2. Повторно
void 0
: Беспокоитесь оundefined
переопределении? Или просто сохранить символы? (Это не поможет вам сundefined
проблемой перекрестного доступа к окну, которая является обычной причиной использованияtypeof
вместо этого.) Кроме того, я просто придирчивый, но это не совсем то же самое, что у меня, поскольку это не позволяет указывать параметр со значениемundefined
. Но это мелочь (как и версия операционной системы). 🙂3. @T.J.Crowder
void 0
возвращает реальноеundefined
значение. Я также думаю, что параметры, указанные какundefined
, должны обрабатываться так же, как если бы их там не было.foo["foo"] = undefined
иdelete foo["foo"]
в моих книгах рассматриваются одинаково. Это то,null
что нужно, если вам не нужно значение в этом параметре.undefined
это не то, что вы должны передавать вручную, но это самоуверенный способ. Спасибо, что указали наreturn false
вещь, которая стала бы проблемой.4. @T.J.Crowder что касается
return false
вещи, которую мы должны использоватьArray.prototype.every
;). IE8 должен умереть, чтобы мы могли использовать ES5.5. @Raynos: Re ECMAScript5: Эй, я все еще жду, когда умрет IE6 . 😉