I find the named parameters feature in C# quite useful in some cases.
calculateBMI(70, height: 175);
What can I use if I want this in JavaScript?
What I don’t want is this:
myFunction({ param1: 70, param2: 175 }); function myFunction(params){ // Check if params is an object // Check if the parameters I need are non-null // Blah blah }
That approach I’ve already used. Is there another way?
I’m okay using any library to do this.
Functions in the functional programming paradigm can be passed to other functions as parameters. These functions are called callbacks. Callback functions can be passed as arguments by directly passing the function's name and not involving them.
Nope, JavaScript/EcmaScript don't support named parameters.
The only thing that matters is the order in which the arguments are passed. This familiar approach is called positional arguments. It is usually fine for cases where you pass one or two arguments since its hard to mess up the order of arguments.
Call by value:- The call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. By default, C programming uses call by value to pass arguments.
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!):
undefined
(that's different from having no value at all). That means you cannot use arguments.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: ...});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With