Allow either named arguments or positional arguments in Javascript

How can I use a function with either argument names ( foo({a: 'hello', b: 'it is me'}) ) or positional arguments ( foo('hello', 'it is me') )?

I understand that named arguments can be modeled by passing an object to a function:

 function foo(options) { options = options || {}; var a = options.a || 'peanut'; // whatever default value var b = options.b || 'butter'; // whatever default value console.log(a, b); } // ES6 allows automatic destructuring function foo({a = 'peanut', b = 'butter'} = {}) { console.log(a, b); } 

But this does not allow me to accept the passed positional arguments.

I would like to use ES6, but something from ES5 would be fine.

+5
source share
3 answers

First of all, I would recommend sticking to one assessment. As you said, use either "named"

 function foo({a = 'peanut', b = 'butter'} = {}) { console.log(a, b); } 

or positional arguments:

 function foo(a = 'peanut', b = 'butter') { console.log(a, b); } 

Choose the one that best suits your function does not mix both .


If you really need both for some reason, standard overload methods are available to you. It will only work if your first positional argument is not an object. I would suggest one of the following idioms:

 function foo(a, b) { // positional is normal case if (arguments.length == 1 && typeof arguments[0] == "object") {a, b} = arguments[0]; console.log(a, b); } 

 function foo({a, b}) { // named is normal case if (arguments.length > 1 || typeof arguments[0] != "object") [a, b] = arguments; console.log(a, b); } 

and if you need default values, it gets ugly anyway:

 function foo(a, b) { var opts = (arguments.length == 1 && typeof arguments[0] == "object") ? arguments[0] : {a, b}; ({a = 'peanut', b = 'butter'} = opts); console.log(a, b); } 
+1
source

I assume something like this will work:

 function foo(...options){ if (typeof options[0] === 'object'){ console.log('expect object', options[0]); }else{ console.log('expect array', options); } } foo('peanut', 'butter'); foo({a:'peanut', b:'butter'}); 
+1
source

I don’t think there is anything for this, but this code should work for your case

 function foo({a = 'peanut', b = 'butter'} = {}) { if (typeof arguments[0] === 'string') { return foo({a: arguments[0], b: arguments[1]}) } console.log(a, b); } 
0
source

Source: https://habr.com/ru/post/1238476/


All Articles