необязательные аргументы javascript в функции
у меня есть типичная функция JavaScript с некоторыми параметрами
my_function = function(content, options) { action }
Если я вызываю функцию так :
my_function (options)
аргумент "options" передается как "content"
как мне обойти это, чтобы я мог либо передать оба аргумента, либо только один ? спасибо
13 ответов:
вы должны решить, в качестве какого параметра вы хотите обработать один аргумент. Вы не можете относиться к нему как к обоим,
content
иoptions
.Я вижу два варианта:
- изменить порядок ваших аргументов, т. е.
function(options, content)
проверить, является ли
options
определено:function(content, options) { if(typeof options === "undefined") { options = content; content = null; } //action }
но тогда вы должны правильно документировать, что произойдет, если вы передадите только один аргумент функции, так как это не сразу понятно, глядя на подпись.
my_function = function(hash) { /* use hash.options and hash.content */ };
а потом звоните:
my_function ({ options: options }); my_function ({ options: options, content: content });
такой:
my_function (null, options) // for options only my_function (content) // for content only my_function (content, options) // for both
или вы также можете различать, какой тип контента вы получили. Параметры, используемые в качестве объекта содержимое используется как строка, поэтому вы можете сказать:
if ( typeof content === "object" ) { options = content; content = null; }
или если вы путаете с переименованием, вы можете использовать массив аргументов, который может быть более простым:
if ( arguments.length === 1 ) { options = arguments[0]; content = null; }
есть 2 способа сделать это.
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.
вы можете передать все ваши дополнительные аргументы в объект в качестве первого аргумента. Второй аргумент-это ваш обратный вызов. Теперь вы можете принять столько аргументов, сколько хотите в своем первом объекте аргумента, и сделать его необязательным следующим образом:
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. Я лично не использовал его, но это выглядит многообещающе.
Я создал простую библиотеку для обработки необязательных аргументов с помощью функций 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 }
основной целью для библиотеки являются интерфейсы модулей, где вы должны быть в состоянии обрабатывать различные вызовы экспортируемых функций модуля.
просто пнуть давно мертвую лошадь, потому что мне пришлось реализовать необязательный аргумент в середине двух или более необходимых аргументов. Используйте
arguments
массив и использовать последние один в качестве обязательного необязательного аргумента.my_function() { var options = arguments[argument.length - 1]; var content = arguments.length > 1 ? arguments[0] : null; }
есть хорошее чтение параметров по умолчанию в 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
.
С ES6:
function test(a, b = 3) { console.log(a, ' ', b); } test(1); // Output: 1 3 test(1, 2); // Output: 1 2