2015-10-04 2 views
1

У меня есть функция с переменными аргументами, аналогичной тойфункции переменной подпись/аргументы

function fn(...args) { 
    let str, arr, obj; 

    if (args.length == 1) { 
     if (typeof args[0] == 'object') { 
      obj = args[0]; 
     } else { 
      str = args[0]; 
     } 
    } else if (args.length == 2) { 
     str = args[0]; 
     if (typeof args[1] == 'object') { 
      obj = args[1]; 
     } else { 
      arr = args[1]; 
     } 
    } else if (args.length == 3) { 
     [str, arr, obj] = args; 
    } 
} 

И API является

fn() 
fn(String str) 
fn(Object obj) 
fn(String str, Array arr) 
fn(String str, Object obj) 
fn(String str, Array arr, Object obj) 

Он намеренно рыхлый по типам (например, некоторые аргументы могут быть неопределенными).

Это код браузера, довольно компактный. Это, безусловно, можно сделать таким образом, но есть ли лучшие рецепты, менее многословные и более удобные в обслуживании? Любой Узел или общие JS-библиотеки, которые могут выполнять грязную работу, сохраняя при этом скромные размеры и зависимости?

+0

Извините, и почему вы считаете это приемлемым вопросом? Он слишком широк. Просто потому, что что-то является вопросом, автоматически не означает, что это разрешено здесь. В 3k rep вы должны знать, какие вопросы сейчас в порядке. –

+0

@JK Каковы ваши личные рекомендации по улучшению вопроса? Я совершенно уверен, что «слишком много возможных ответов или хороших ответов было бы слишком длинным» не так. Хорошие ответы, которые могут мешать мне изобретать колесо, существуют, и их не будет слишком много. – estus

+0

Ничего общего с вопросом, но это не будет работать так, как вы думаете: 'if (typeof args [1] == 'object') { obj = args [1]; } else { arr = args [1]; } ', так как' typeof' Array также является «объектом». – Buzinas

ответ

2

«Проблема» Я вижу, что вы не только перегружаетесь переменными аргументами, но и перегружаете аргумент типов. Комбинация приводит к беспорядочной реализации, которая только вредит вам в долгосрочной перспективе.

Вот еще один способ написать его, который использует вспомогательную функцию, но вы все еще находитесь в мире боли (более подробно).

function fn(...args) { 
    function aux(str, arr, obj) { 
     // this function will always have str, arr, and obj 
    } 

    // Warning: this has an error anyway because (typeof []) is also 'object' 

    switch (args.length) { 
     case 1: return typeof args[0] === 'object' 
       ? aux(null, null, args[0]) 
       : aux(args[0], null, null); 

     case 2: return typeof args[0] === 'object' 
       ? aux(args[0], null, args[1]) 
       : aux(args[0], args[1], null); 

     case 3: return aux(args[0], args[1], args[2]); 
    } 


} 

С выше реализации, у вас есть уникальные способы для вызова вашей функции, все из которых предназначены, чтобы быть приемлемым и целесообразным.

Против

  1. неподходящих для запоминания API - которые приводят я получу, на основании которых аргументы? Когда я передаю строку и объект, который я делаю первым? и т. д.
  2. Кошмар Refactor - Если функция когда-либо понадобится изменить, вам необходимо поддерживать все 5 разновидностей вызовов. После того, как вы навязываете все 5 действий с помощью одной функции api, нет никакого способа разделить поведение, не нарушая существующий код, написанный против этой функции.
  3. Необычно сложная плита котла в определении функции. Большинство функций просто сопоставляют аргументы с их локальными параметрами, и все это позаботится о вас самим JavaScript. В вашей функции теперь есть куча кода, изменяющего поведение JavaScript, и из-за этого ухудшается читаемость кода. Этот шаблон будет умножен на каждую функцию, которую вы пишете с помощью такого «дизайна».
  4. Жестко распознаваемые типы - typeof [] вернется 'object' не 'array', как вы думаете. Вам нужно будет написать тонны угловых шкафов, чтобы убедиться, что вы правильно определяете все ваши типы. JavaScript не является типизированным языком и поэтому пытается согласовать поведение, основанное на typeof, так как ваш механизм обнаружения ошибок приведет к разным головным болям. Весь этот дополнительный код означает большую вероятность ошибок, больше кода для поддержки, и в конечном итоге пострадает общее качество вашего программного обеспечения.

Pros

  1. этот раздел намеренно оставлена ​​пустой

Разработчики часто делают ошибку, что потому язык допускает определенный образ мышления, что любой код, они придумайте, до тех пор, пока он компилирует/выполняет, что все в порядке.

Это очень большое заблуждение, и часто почему опытные разработчики ценят/предпочитают язык с большей строгостью и большими ограничениями.

В любом случае, удачи.

Смежные вопросы