ES6 introduces a bevy of convenient "syntactic sugar". Among them are the default parameter capabilities of JavaScript functions, as well as rest parameters. I'm finding that my console (or devTools) complains (i.e., throws an error) whenever attempting to set a default parameter value on a rest parameter. I've found surprisingly few references to this particular issue elsewhere and am wondering if 1.) it is possible to do so and 2.) why not (assuming it's not possible).
As an example, I've contrived a trivial (but, hopefully still purposeful) example. In this first iteration of the function, I've constructed the function such that it will work (which is to say, without giving the rest parameter a default value).
const describePerson = (name, ...traits) => `Hi, ${name}! You are ${traits.join(', ')}`;
describePerson('John Doe', 'the prototypical placeholder person');
// => "Hi, John Doe! You are the prototypical placeholder person"
However, now with the default:
const describePerson = (name, ...traits = ['a nondescript individual']) => `Hi, ${name}! You are ${traits.join(', ')}`;
describePerson('John Doe');
// => Uncaught SyntaxError: Unexpected token =
Any help is greatly appreciated.
The default parameter is a way to set default values for function parameters a value is no passed in (ie. it is undefined ). In a function, Ii a parameter is not provided, then its value becomes undefined . In this case, the default value that we specify is applied by the compiler.
Setting JavaScript default parameters for a function In JavaScript, a parameter has a default value of undefined. It means that if you don't pass the arguments into the function, its parameters will have the default values of undefined . The say() function takes the message parameter.
Short answer: No. Fortunately, you can simulate them. Many programming languages like C++ or modern JavaScript have a simple option to call a function without providing values for its arguments.
No, rest parameters cannot have a default initialiser. It is not allowed by the grammar because the initialiser would never be run - the parameter always gets assigned an array value (but possibly an empty one).
What you want to do could be achieved by either
function describePerson(name, ...traits) {
if (traits.length == 0) traits[0] = 'a nondescript individual';
return `Hi, ${name}! You are ${traits.join(', ')}`;
}
or
function describePerson(name, firstTrait = 'a nondescript individual', ...traits) {
traits.unshift(firstTrait);
return `Hi, ${name}! You are ${traits.join(', ')}`;
}
// the same thing with spread syntax:
const describePerson = (name, firstTrait = 'a nondescript individual', ...otherTraits) =>
`Hi, ${name}! You are ${[firstTrait, ...otherTraits].join(', ')}`
Just came to add a cleaner defaults system:
const describePerson = (name, ...traits) => {
traits = Object.assign(['x', 'y'], traits);
return `Hi, ${name}, you are ${traits.join(', ')}`;
}
describePerson('z'); // you are z, y
describePerson('a', 'b', 'c'); // you are a, b, c
describePerson(); // you are x, y
This works because arrays are objects whose indices are keys, and Object.assign
overrides the keys of the first object present in the second one with the values of the second one.
If the second one has no index 1, then it won't be overwritten, but if it has index 0, the first array's index 0 will be overwritten by the second, which is the behaviour you expect when defaulting
Note that spreading arrays is not the same operation as spreading objects, which is why [....['x', 'y'], ...traits]
wouldn't overwrite the indices
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