Since 2015, JavaScript has improved immensely.
It’s much more pleasant to use it now than ever.
In this article, we’ll look at working with parameters and the rest syntax.
Why does undefined
trigger default values?
undefined
indicates that something doesn’t exist.
This is different from null
in that it indicates an empty value.
Therefore, only undefined
will trigger default values to be set.
Referring to Other Parameters in Default Values
We can refer to other parameters in default values.
For example, if we have:
function foo(x = 13, y = x) {
console.log(x, y);
}
If we call foo();
, then we get that x
and y
are both 13.
If we call foo(7);
, then we get that x
and y
are both 7.
And if we call foo(17, 12);
, then we get that x
is 17 and y
is 12.
Referring to Inner Variables in Default Values
If we have code like:
const x = 'outer';
function foo(a = x) {
const x = 'inner';
console.log(a);
}
foo()
where we assign the outer variable as a value of a parameter, then even if we define a variable with the same name inside it, it’ll refer to the outer one.
We assigned the default value of a
to x
, so even if we defined x
again with a new value, we still get a
is 'outer'
.
If there’s no x
above the function, we’ll get a ReferenceError.
This also applies to parameters when a parameter is a function.
For example, if we have:
const bar = 2;
function foo(callback = () => bar) {
const bar = 3;
callback();
}
foo();
The callback
is assigned to the function that returns bar
by default, so that’s what will be called if we call callback
with no callback passed into it.
So callback
returns 2.
Rest Parameters
Rest parameters let us capture arguments that aren’t set to any parameter.
For instance, if we have:
function foo(x, ...args) {
console.log(x, args);
//···
}
foo('a', 'b', 'c');
Then x
is 'a'
and args
is ['b', 'c']
.
If there’re no remaining parameters, then args
will be set to an empty array.
This is a great replacement to the arguments
object.
With ES5 or earlier, the only way to get all the arguments of a function is with the arguments
object:
function logArgs() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
With ES6 or later, we can just use rest parameters to do the same thing.
For instance, we can write:
function logArgs(...args) {
for (const arg of args) {
console.log(arg);
}
}
We log all the arguments with the for-of loop.
Combining Destructuring and Access to the Destructured Value
Since the rest operator gives us an array, we can destructure it.
For example, we can write:
function foo(...args) {
let [x = 0, y = 0] = args;
console.log(x, y);
}
We set the first 2 entries of args
to x
and y
respectively.
And we set their default values to 0.
The destructuring also works for object parameters.
For example, we can write:
function bar(options = {}) {
const {
x,
y
} = options;
console.log(x, y);
}
We have the bar
function that has the options
parameter.
We destructured the object to the x
and y
variables.
arguments
is an iterable object.
We can use the spread operator with ES6 to convert it to an array.
For example, we can write:
function foo() {
console.log([...arguments]);
}
Then the array will have all the arguments.
Conclusion
We can use rest parameters to get all arguments passed into a function.
And we can refer to other values as default values.