Javascript необязательные аргументы в функции
У меня есть типичная функция javascript с некоторыми параметрами
my_function = function(content, options) { action }
если я вызываю функцию как таковую:
my_function (options)
аргумент "параметры" передается как "контент"
как мне обойти это, чтобы я мог либо передать оба аргумента, либо один?
спасибо
Ответы
Ответ 1
Вы должны решить, каким параметром вы хотите обрабатывать один аргумент. Вы не можете относиться к нему как к content
, так и к options
.
Я вижу две возможности:
- Либо измените порядок ваших аргументов, т.е.
function(options, content)
-
Проверьте, не определено ли options
:
function(content, options) {
if(typeof options === "undefined") {
options = content;
content = null;
}
//action
}
Но тогда вы должны правильно документировать, что произойдет, если вы передадите только один аргумент функции, так как это не сразу видно, глядя на подпись.
Ответ 2
my_function = function(hash) { /* use hash.options and hash.content */ };
а затем вызовите:
my_function ({ options: options });
my_function ({ options: options, content: content });
Ответ 3
Вот так:
my_function (null, options) // for options only
my_function (content) // for content only
my_function (content, options) // for both
Ответ 4
Или вы также можете различать, какой тип контента вы получили. Параметры, используемые для использования в качестве объекта, являются строкой, поэтому вы можете сказать:
if ( typeof content === "object" ) {
options = content;
content = null;
}
Или, если вас путают с переименованием, вы можете использовать массив аргументов, который может быть более простым:
if ( arguments.length === 1 ) {
options = arguments[0];
content = null;
}
Ответ 5
Есть два способа сделать это.
1)
function something(options) {
var timeToLive = options.timeToLive || 200; // default to 200 if not set
...
}
2)
function something(timeToDie /*, timeToLive*/) {
var timeToLive = arguments[1] || 200; // default to 200 if not set
..
}
В 1), options
- это объект JS, для которого требуются все атрибуты. Это легче поддерживать и расширять.
В 2) сигнатура функции понятна для чтения и понимания того, что может быть предоставлен второй аргумент. Я видел этот стиль, используемый в коде Mozilla и документации.
Ответ 6
Вы можете передать все необязательные аргументы в объекте в качестве первого аргумента. Второй аргумент - ваш обратный вызов. Теперь вы можете принять столько аргументов, сколько хотите, в свой первый объект аргумента и сделать его необязательным:
function my_func(op, cb) {
var options = (typeof arguments[0] !== "function")? arguments[0] : {},
callback = (typeof arguments[0] !== "function")? arguments[1] : arguments[0];
console.log(options);
console.log(callback);
}
Если вы вызываете его без передачи аргумента options, он будет по умолчанию пустым объектом:
my_func(function () {});
=> options: {}
=> callback: function() {}
Если вы вызываете его с аргументом options, вы получаете все свои параметры:
my_func({param1: 'param1', param2: 'param2'}, function () {});
=> options: {param1: "param1", param2: "param2"}
=> callback: function() {}
Это, очевидно, может быть изменено для работы с большим количеством аргументов, чем два, но это становится более запутанным. Если вы можете просто использовать объект в качестве своего первого аргумента, вы можете передать неограниченное количество аргументов с помощью этого объекта. Если вам абсолютно необходимы дополнительные аргументы (например, my_func (arg1, arg2, arg3,..., arg10, fn)), я бы предложил использовать библиотеку, например ArgueJS. Я лично его не использовал, но выглядит многообещающе.
Ответ 7
Я создал простую библиотеку для обработки необязательных аргументов с функциями JavaScript, см. https://github.com/ovatto/argShim. Библиотека разработана с учетом Node.js, но ее следует легко портировать для работы, например. браузеры.
Пример:
var argShim = require('argShim');
var defaultOptions = {
myOption: 123
};
var my_function = argShim([
{optional:'String'},
{optional:'Object',default:defaultOptions}
], function(content, options) {
console.log("content:", content, "options:", options);
});
my_function();
my_function('str');
my_function({myOption:42});
my_function('str', {myOption:42});
Вывод:
content: undefined options: { myOption: 123 }
content: str options: { myOption: 123 }
content: undefined options: { myOption: 42 }
content: str options: { myOption: 42 }
Основной целью библиотеки являются интерфейсы модулей, где вам нужно иметь возможность обрабатывать различные вызовы экспортируемых функций модуля.
Ответ 8
Просто, чтобы выгнать длинную мертвую лошадь, потому что мне пришлось реализовать необязательный аргумент в середине двух или более обязательных аргументов. Используйте массив arguments
и используйте последний как необходимый необязательный аргумент.
my_function() {
var options = arguments[argument.length - 1];
var content = arguments.length > 1 ? arguments[0] : null;
}
Ответ 9
В разделе ES6 на сайте MDN есть приятное чтение параметров по умолчанию.
В ES6 вы можете сделать следующее:
secondDefaultValue = 'indirectSecondDefaultValue';
function MyObject( param1 = 'firstDefaultValue', param2 = secondDefaultValue ){
this.first = param1;
this.second = param2;
}
Вы можете использовать это также следующим образом:
var object = new MyObject( undefined, options );
Будет установлено значение по умолчанию 'firstDefaultValue'
для первого param1
и вашего options
для второго param2
.
Здесь демонстрация в скрипке
Ответ 10
Вы получите значение аргумента un прошедшего аргумента как undefined.
Но в вашем случае вам нужно передать хотя бы нулевое значение в первом аргументе.
Или вам нужно изменить определение метода, например
my_function = function(options, content) { action }
Ответ 11
Назовите это
my_function ("", options);
Ответ 12
Вы также можете поместить чек в действие, например:
options = !options ? content : options
, который устанавливает параметры для первого аргумента, если не было передано ни секунды, а затем вы просто устанавливаете контент в значение null (или игнорируете его, однако вы хотите проверить это)