Is there a way to provide named parameters in a function call in JavaScript?
ES2015 and later
In ES2015, parameter destructuring can be used to simulate named parameters. It would require the caller to pass an object, but you can avoid all of the checks inside the function if you also use default parameters:
myFunction({ param1 : 70, param2 : 175});
function myFunction({param1, param2}={}){
// ...function body...
}
// Or with defaults,
function myFunc({
name = 'Default user',
age = 'N/A'
}={}) {
// ...function body...
}
ES5
There is a way to come close to what you want, but it is based on the output of Function.prototype.toString
[ES5], which is implementation dependent to some degree, so it might not be cross-browser compatible.
The idea is to parse the parameter names from the string representation of the function so that you can associate the properties of an object with the corresponding parameter.
A function call could then look like
func(a, b, {someArg: ..., someOtherArg: ...});
where a
and b
are positional arguments and the last argument is an object with named arguments.
For example:
var parameterfy = (function() {
var pattern = /function[^(]*\(([^)]*)\)/;
return function(func) {
// fails horribly for parameterless functions ;)
var args = func.toString().match(pattern)[1].split(/,\s*/);
return function() {
var named_params = arguments[arguments.length - 1];
if (typeof named_params === 'object') {
var params = [].slice.call(arguments, 0, -1);
if (params.length < args.length) {
for (var i = params.length, l = args.length; i < l; i++) {
params.push(named_params[args[i]]);
}
return func.apply(this, params);
}
}
return func.apply(null, arguments);
};
};
}());
Which you would use as:
var foo = parameterfy(function(a, b, c) {
console.log('a is ' + a, ' | b is ' + b, ' | c is ' + c);
});
foo(1, 2, 3); // a is 1 | b is 2 | c is 3
foo(1, {b:2, c:3}); // a is 1 | b is 2 | c is 3
foo(1, {c:3}); // a is 1 | b is undefined | c is 3
foo({a: 1, c:3}); // a is 1 | b is undefined | c is 3
DEMO
There are some drawbacks to this approach (you have been warned!):
- If the last argument is an object, it is treated as a "named argument objects"
- You will always get as many arguments as you defined in the function, but some of them might have the value
undefined
(that's different from having no value at all). That means you cannot usearguments.length
to test how many arguments have been passed.
Instead of having a function creating the wrapper, you could also have a function which accepts a function and various values as arguments, such as
call(func, a, b, {posArg: ... });
or even extend Function.prototype
so that you could do:
foo.execute(a, b, {posArg: ...});
How to use a default value for named parameter in Javascript
I think you're looking for default parameters
const someFunc = ({ a = "foo" }) => {
console.log(a);
}
someFunc({}); // "foo"
someFunc({a: "bar"}); // "bar"
Using named parameters in node.js
The standard Javascript way is to pass an "options" object like
info({spacing:15, width:46});
used in the code with
function info(options) {
var spacing = options.spacing || 0;
var width = options.width || "50%";
...
}
as missing keys in objects return undefined
that is "falsy".
Note that passing values that are "falsy" can be problematic with this kind of code... so if this is needed you have to write more sophisticated code like
var width = options.hasOwnProperty("width") ? options.width : "50%";
or
var width = "width" in options ? options.width : "50%";
depending on if you want to support inherited options or not.
Pay also attention that every "standard" object in Javascript inherits a constructor
property, so don't name an option that way.
Calling a function without reassigning named argument
You could store the values as property of the function.
function mainFun({ val1 = mainFun.val1, val2 = mainFun.val2, val3 = mainFun.val3 }) {
mainFun.val1 = val1;
mainFun.val2 = val2;
mainFun.val3 = val3;
console.log(val1, val2, val3);
}
<button onclick="mainFun({ val1: 'Caller 1' })">First Event</button>
<button onclick="mainFun({ val2: 'Caller 2' })">Second Event</button>
<button onclick="mainFun({ val3: 'Caller 3' })">Third Event</button>
JavaScript (ES6): Named parameters and default values
You need a default object.
var fun = ({ first = 1, last = 1 } = {}) => 1 * first + 2 * last;
// ^^^^
console.log(fun({ first: 1, last: 2 }));
console.log(fun({ last: 1, first: 2 }));
console.log(fun());
Using named parameters JavaScript (based on typescript)
True named parameters don't exist in JavaScript nor in TypeScript but you can use destructuring to simulate named parameters:
interface Names {
name1: boolean
name2: boolean
name3: boolean
name4: boolean
}
function myFunction({name1, name2, name3, name4}: Names) {
// name1, etc. are boolean
}
Notice: The type Names
is actually optional. The following JavaScript code (without typing) is valid in TS:
function myFunction({name1, name2, name3, name4}) {
// name1, etc. are of type any
}
React pass parameters by names when calling a function
When you call the function, you just call it normally like any other function. There's nothing special about calling functions with default params set. However, it usually doesn't make sense to have too many default params, especially if you need to often specify one after the first one, since then you end up having to specify the value of the first "optional" param every time anyways.
onChange={(e) => this.handleChange(false, true, e)}
Non-default parameters should always go first by the way, so that you don't need to specify every default param:
handleChange(event, required = false, test = false)
Then you could call any of:
handleChange(event) // required=false, test=false
handleChange(event, true) // required=true, test=false
handleChange(event, true, true) // required=true, test=true
...
Maybe instead you want to create a callback that takes an options object, and set some of the values based on defaults:
handleChange(event, options = {}) {
const required = options.required ? options.required : false;
const test = options.test ? options.test : false;
...
}
Then you would call it like:
handleChange(event) // required=false, test=false
handleChange(event, { required: true }) // required=true, test=false
handleChange(event, { test: true }) // required=false, test=true
handleChange(event, { required: true, test: true }) // required=true, test=true
Related Topics
Controller Not a Function, Got Undefined, While Defining Controllers Globally
How to Pass Command Line Arguments to a Node.Js Program
JavaScript: Object Literal Reference in Own Key'S Function Instead of 'This'
How to Get the Difference Between Two Dates in JavaScript
How to Change Fontsize by JavaScript
Angularjs CSS Animation + Done Callback
Shell Tool Which Renders Web Site Including JavaScript
Convert a String to a Template String
Count the Number of Occurrences of a Character in a String in JavaScript
Why This JavaScript Regex Doesn't Work
Is "Clear" a Reserved Word in JavaScript
Read :Hover Pseudo Class with JavaScript