Javascript — передача аргументов в функцию

Я всегда передавал аргументы такой функции:

setValue('foo','#bar')

function setValue(val,ele){
    $(ele).val(val);
};

Прости глупый пример. Но недавно я работал над проектом, в котором есть несколько функций, которые принимают много аргументов. Итак, я начал передавать аргументы как объект (не уверен, что это правильный способ выразить это), например:

setValue({
  val:'foo',
  ele:'#bar'
});

И затем в функции:

function setValue(options){

    var value = options.val;
    var element = options.ele;  

    $(element).val(value);

};

Мой вопрос в том, есть ли лучший способ сделать это? Является ли обычной практикой (или нормально) называть эти «варианты»? И вам обычно нужно «распаковывать» (из-за отсутствия лучшего термина) параметры и устанавливать локальные переменные внутри функции? Я делал это таким образом, если один из них не был определен.

Я действительно стараюсь не создавать вредных привычек и не писать кучу уродливого кода. Любая помощь приветствуется и + мной. Спасибо.


person jyoseph    schedule 04.02.2011    source источник
comment
Вроде все правильно делаешь. Кроме того, да, {} является объектом (в буквальном обозначении) в JS. Мой единственный комментарий: зачем вообще использовать локальное подобное значение, когда вы можете просто передать options.val другой функции (но это имеет смысл, если вам нужно ссылаться на него более одного раза).   -  person Kevin Le - Khnle    schedule 04.02.2011
comment
Да, вот что мне было любопытно. Так что я думаю, что это не обязательно для такой функции, как в примере, но если бы мне нужно было много ссылаться на переменную, тогда установка имела бы смысл. Прохладный.   -  person jyoseph    schedule 04.02.2011


Ответы (6)


Я делаю то же самое, за исключением того, что не объявляю новую переменную для каждой опции внутри функции.

Я думаю, что options — хорошее название для него, хотя я сокращаю его до opts.

У меня всегда есть объект "по умолчанию" внутри функции, который указывает значения по умолчанию для каждой доступной опции, даже если это просто null. Я использую jQuery, поэтому я могу просто использовать $.extend для объединения параметров по умолчанию и указанных пользователем параметров, например: var opts = $.extend({}, defaults, opts);

person simshaun    schedule 04.02.2011
comment
Мне нравится идея $.extend. Собираюсь изучить это дальше, спасибо! - person jyoseph; 04.02.2011

Я считаю, что это отличный образец. Я слышал, что объект параметров, подобный этому, на других языках называется «объектом построителя» (по крайней мере, в контексте создания объекта). Вот некоторые из преимуществ:

  • Пользователям вашей функции не нужно беспокоиться о том, в каком порядке находятся параметры. Это особенно полезно в таких случаях, как ваш, когда метод принимает много аргументов. Их легко перепутать, и JavaScript не будет жаловаться!
  • Некоторые параметры легко сделать необязательными (это удобно при написании плагина или утилиты).

Хотя есть некоторые подводные камни. В частности, пользователь вашей функции не мог указать некоторые параметры, и ваш код задохнулся бы (обратите внимание, что это также может произойти с обычной функцией JS: пользователю все еще не нужно указывать правильные аргументы). Хороший способ справиться с этим — предоставить значения по умолчанию для параметров, которые не требуются:

var value = options.val || 0;
var element = options.ele || {};  

$(element).val(value);

Вы также можете немедленно вернуться из функции или сгенерировать исключение, если правильный аргументы не предоставляются.

Хорошим ресурсом для изучения того, как обрабатывать объекты построителя, является проверка источника таких вещей, как jQueryUI.

person Andrew Whitaker    schedule 04.02.2011
comment
Звездный пример с var value = options.val || 0 - это очень поможет. Тоже отличные ссылки. Благодаря тонну! - person jyoseph; 04.02.2011

Я понимаю, что этому вопросу уже год, но я думаю, что самый чистый способ передать произвольное количество аргументов функции JavaScript — использовать массив и встроенный метод apply:

fun.apply(object, [argsArray])

Где fun — это функция, object — ваша область/контекст, в котором вы хотите, чтобы функция выполнялась, а argsArray — это массив аргументов (который может содержать любое количество передаваемых аргументов.

Текущая ошибка заключается в том, что аргументы должны быть массивом (литералом или объектом), а не массивоподобным объектом, таким как {'arg' : 6, 'arg2' : "stuff"}. ECMAScript 5 позволит вам передавать массивоподобные объекты, но на данный момент он работает только в FireFox, а не в IE9 или Chrome.

person Graham Conzett    schedule 25.01.2012

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

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

person RichardTheKiwi    schedule 04.02.2011

Стоит помнить, что у всех функций есть бонусный параметр arguments, который представляет собой объект, очень похожий на массив JS (у него есть length, но нет функций массива), который содержит все переданные параметры.

Полезно, если вы хотите передать ряд параметров (например,

function Sum() {
    var i, sum = 0;
    for (i=0; i < arguments.length; i++){
        sum+=arguments[i];
    }
    return sum;
};

Если это не так и у вас просто много параметров, используйте объект params, как вы описали.

person StuperUser    schedule 25.01.2012

В этой практике нет ничего плохого.

«Опции» кажется таким же хорошим именем, как и любое другое.

Вам не нужно «распаковывать» их, но если вы будете обращаться к одному и тому же элементу несколько раз, будет немного эффективнее ссылаться на них в локальных переменных, потому что доступ к локальным переменным обычно быстрее, чем поиск свойств.

person user113716    schedule 04.02.2011