необязательные аргументы javascript в функции


у меня есть типичная функция JavaScript с некоторыми параметрами

my_function = function(content, options) { action }

Если я вызываю функцию так :

my_function (options)

аргумент "options" передается как "content"

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

13 51

13 ответов:

вы должны решить, в качестве какого параметра вы хотите обработать один аргумент. Вы не можете относиться к нему как к обоим,content и options.

Я вижу два варианта:

  1. изменить порядок ваших аргументов, т. е. function(options, content)
  2. проверить, является ли 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

вы получите значение переданного аргумента un как неопределенное. Но в вашем случае вы должны передать по крайней мере нулевое значение в первом аргументе.

или вы должны изменить определение метода как

my_function = function(options, content) { action }

позвоните вот так

my_function ("", options);

вы также можете поставить галочку в действии, как: options = !options ? content : options это устанавливает параметры для первого аргумента, если второй не был передан, а затем вы просто устанавливаете содержимое в null (или игнорируете его, однако вы хотите это проверить)