Как сократить этот код

#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 . 😉