Стоит ли использовать переключатель с отказом для обработки аргументов по умолчанию в Javascript?

Недавно я узнал, что вы можете использовать аккуратный оператор switch с аварийным переходом, чтобы установить значения аргументов по умолчанию в Javascript:

function myFunc(arg1, arg2, arg3) {
    //replace unpassed arguments with their defaults:
    switch (arguments.length) {
        case 0 : arg1 = "default1";
        case 1 : arg2 = "default2";
        case 2 : arg3 = "default3";
    }
}

Мне это очень понравилось, так как оно не только очень короткое, но и работает на основе фактически переданных параметров, не полагаясь на специальный класс значений (null, false и т. д.), служащих заполнителями, как в более традиционных версии:

function myFunc(arg1, arg2, arg3){
    //replace falsy arguments with their defaults:
    arg1 = arg1 || "default1";
    arg2 = arg2 || "default2";
    arg3 = arg3 || "default3";
}

Поначалу, увидев версию, использующую переключатель, я подумал, что мне следует рассмотреть возможность использования его «по умолчанию» вместо версии ||.

Переключатель fall, тем не менее, делает его ненамного длиннее, и его преимущество заключается в том, что он гораздо более «надежен» в том смысле, что ему не важны типы параметров. В общем случае кажется хорошей идеей не беспокоиться о том, что произойдет со всеми ложными значениями ('', 0, null, false ...) всякий раз, когда мне нужно сделать функцию с параметрами по умолчанию.

Затем я бы зарезервировал arg = arg || x для реальных случаев, когда я хочу проверить достоверность, вместо того, чтобы использовать его как общее правило для параметра по умолчанию.

Однако я нашел очень мало примеров этого шаблона, когда я делал поиск кода для него поэтому мне пришлось надеть шляпу скептика. Почему я не нашел других примеров этой идиомы?

  • Это сейчас очень хорошо известно?
  • Я недостаточно хорошо искал? Меня смутило большое количество ложных срабатываний?
  • Есть ли что-то, что делает его хуже альтернатив?

Некоторые причины, которые я (и некоторые из комментариев) мог придумать, чтобы избежать switch(arguments.length):

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

  • Возможно, большую часть времени мы действительно хотим проверить на правдивость? Использование категории значений в качестве заполнителей также позволяет отображать параметры по умолчанию в середине, а не только в конце: myFunc('arg1', null, 'arg3')

  • Возможно, большинство людей просто предпочитают очень короткие arg = arg || "default" и большую часть времени нас просто не волнуют ложные значения?

  • Возможно, доступ к arguements является злом/неэффективным?

  • Возможно, у этого типа провала переключателя есть плохая часть, о которой я не подумал?

Достаточно ли этих недостатков, чтобы избежать использования switch(arguments.length) в качестве основного шаблона аргумента по умолчанию, или это изящный прием, который мне следует сохранить и использовать в моем коде?


person hugomg    schedule 05.01.2012    source источник
comment
Я никогда не знал об этой идиоме, но, глядя на нее, я вижу по крайней мере одно предостережение: передача undefined делает arguments.length === 2, в то время как вы, вероятно, захотите заменить переданное undefined значением по умолчанию (как это делает ||).   -  person pimvdb    schedule 05.01.2012
comment
Интересный подход. Хотя это будет работать только в том случае, если вы всегда предоставляете все предыдущие параметры. Например, jQuery позволяет опускать параметры в середине, такие как $.get(url, callback) вместо $.get(url, data, callbacl). switch не мог провести различие между разными типами параметров. Это также приведет к ошибке, если будут переданы параметры заполнения, такие как foo(1, null, 3), потому что нужно установить третий параметр, а не второй (edit что сказал pimvdb). Так что, возможно, это причины, по которым он не так популярен; он недостаточно гибкий.   -  person Felix Kling    schedule 05.01.2012
comment
Я думаю, что еще одна причина, по которой это не используется, заключается в том, что требуется дополнительная работа, если вы реорганизуете метод, чтобы иметь другую сигнатуру, тогда как типичный метод по-прежнему будет работать нормально.   -  person Justin Breitfeller    schedule 05.01.2012
comment
В первом комментарии, по крайней мере, в Chrome, параметры, переданные как неопределенные, учитываются в arguments.length.   -  person HBP    schedule 05.01.2012
comment
@Hans B PUFAL: Похоже, мы на одной волне. myFunc(undefined, undefined) не изменит первые два undefined, но изменит третий undefined.   -  person pimvdb    schedule 05.01.2012
comment
Это не конструктивный вопрос.   -  person Daniel A. White    schedule 05.01.2012
comment
Этот вопрос должен быть закрыт.   -  person Daniel A. White    schedule 05.01.2012
comment
@DanielA.White: Ну, формулировка, возможно, была не самой лучшей, но я все же думаю, что имеет смысл сравнить эту идиому с другими, чтобы иметь возможность сделать осознанный выбор при написании моего кода.   -  person hugomg    schedule 05.01.2012
comment
пожалуйста, отредактируйте свой вопрос и уточните это.   -  person Daniel A. White    schedule 05.01.2012
comment
Думаю достаточно конструктивно.   -  person Lightness Races in Orbit    schedule 05.01.2012
comment
Да, я не вижу веской причины закрывать его, и тем более оправдывать два комментария с разницей в пять минут о том, насколько это плохой вопрос.   -  person Dave Newton    schedule 05.01.2012


Ответы (2)


Поскольку вопрос был обновлен, это действительно вопрос мнения. Есть ряд функций javascript, которых многие советуют избегать, например, switch и ternary. Вот почему не так много информации о некоторых из этих функций.

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

Так что, если вам нравится делать это таким образом, и вы не беспокоитесь о мнениях (или уровне навыков) тех, кто работает над вашим кодом. В любом случае, ваш подход будет работать. Я сам иногда использовал оператор switch, и хотя я не думаю, что он действительно "хороший" или "плохой", трудно найти ситуацию, в которой он требуется.

Вы спросили, как я могу сделать это без цепочки if-else:

function myFunc(args) {
    var allArgs = {
        arg1:"default1",
        arg2:"default2",
        arg3:"default3"
    };
    for (var key in args) {
        allArgs[key] = args[key];        
    }
}
myFunc({arg1:null, arg3:'test'})
person Nick Hagianis    schedule 05.01.2012
comment
Я думаю, что шаблон переключения был больше приспособлен для случаев, когда функция получает аргументы из списка, как в f(arg1, arg2). Но у вас есть смысл сказать, что все обсуждение не имеет значения, поскольку именованные параметры обычно просто лучше. - person hugomg; 06.01.2012

Просто предположение, но Дуг Крокфорд не одобряет использование операторов switch в «JavaScript: хорошие стороны». Его логика заключается в том, что операторы switch являются распространенным источником ошибок, потому что их трудно найти при использовании логики «проваливания». Легко увидеть, когда запускается случай, но часто трудно определить, был ли охвачен каждый случай в наборе результатов, особенно если это не ваш код.

person Ted    schedule 05.01.2012
comment
+1 Вероятно, есть лучший способ выполнить то, что вы пытаетесь сделать, без использования оператора switch. некоторая информация о хороших и плохих частях javascript: youtube.com/watch?v=RO1Wnu- хКоЮ - person Nick Hagianis; 05.01.2012
comment
@NickHagianis: Что может быть здесь альтернативой? Обычный стиль || имеет другую семантику (как обсуждалось в вопросе), и использование цепочки if-else намного более подробно. - person hugomg; 05.01.2012
comment
Это хороший ответ на вопрос: почему я не нашел больше примеров этой идиомы? Но я не уверен, что логика верна. Многие программисты JavaScript, кажется, думают, что мнения Крокфорда о том, какие части JavaScript хороши, а какие плохи, абсолютно верны. Лично я не согласен с Крокфордом здесь: операторы switch могут быть причудливыми, но я никогда не считал их значительным источником ошибок в любом коде, который их использует. - person Daniel Pryden; 06.01.2012