JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.
In this article, we’ll look at the best ways to write functions that are less likely to cause errors.
Use Arrow Functions as Much as Possible
JavaScript arrow functions are great. They let us write functions in a shorter and cleaner way.
Also, we don’t have to worry about the value of this
inside a function. The value of this
is always a pain to think about since it takes on a different value in different locations.
Also, we don’t have to worry about the value of the arguments
object since it doesn’t bind to it.
Therefore, we should use it as much as possible. For instance, we can write something like:
const arr = [1, 2, 3];
const arr2 = arr.map(x => x * 2);
In the code above, x => x * 2
is our arrow function. As we can see, it’s short, and since it’s one line, we don’t have to write return
explicitly to return x * 2
. One line functions are much cleaner.
We don’t have to write out the function
keyword all the time to declare a function.
Also, we also can’t call bind
, call
, or apply
with it, so that we don’t have to worry about those methods either. This is another reason that we should use arrow functions as much as possible since there are fewer risks for errors from calling these methods.
They also can’t be used as constructor functions so we can’t use the new
keyword with them. This is good because don’t want to use constructor functions anymore with the new class syntax.
Another good thing is that they don’t have a prototype
property since they can’t be used as constructor functions. That’s another place that we can’t commit errors in the code.
Also, there’re no function declarations with arrow functions, so they can’t be hoisted. This means that they can only be referenced after they’re defined. This removes a lot of confusion with where we can call or reference an arrow function.
They can be used as top-level functions, as methods of objects, or be nested anywhere.
For instance, we can write:
const obj = {
foo: () => {
console.log('foo');
}
}
So we can call the obj.foo
method to log 'foo'
.
We can also write:
const bar = () => {
const foo = () => {
console.log('foo');
}
}
to nest foo
inside bar
.
Therefore, they’re good to use in places other than for constructor functions. We don’t really want to use constructor functions anyways since there’s the class syntax which actively checks for errors in our code instead of letting errors slide with constructor functions.
This is even more critical when we inherit from another constructor function.
Using the Rest Operator for Getting Long List of Arguments
The rest operator should always be used instead of the arguments
object if we have a long list of arguments passed into our function.
It’s denoted by ...
in the function signature and it returns the extra arguments that aren’t set as the value of the named parameters as an array.
They work with arrow functions and traditional functions. For instance, we can use the rest operator as follows:
function f(a, b, ...args) {
console.log(args);
}
When we call f(1, 2, 3, 4, 5);
then args
is [3, 4, 5]
since 1 is set to a
and 2 is set to b
.
We can also use them with arrow functions:
const f = (a, b, ...args) => {
console.log(args);
}
Then we get the same result as before.
This way, we don’t have to use the arguments
object to get the arguments, or use call
or apply
to call a function with extra arguments.
Like any array, we can use the destructuring syntax with it. For instance, we can write:
const f = (a, b, ...[d, e]) => {
console.log(d, e);
}
Then when we call it as follows:
f(1, 2, 3, 4, 5);
We get that d
is 3, e
is 4. Note that we don’t have to destructure all the arguments that are passed in.
This is much better than the arguments
object since it’s an array rather than an array-like object and we can use destructuring syntax with it.
Conclusion
Arrow functions should be used in our JavaScript code except when we need to create constructors or reference this
in an object method.
The rest operator is the best way to get the arguments of a function that isn’t assigned to named parameters.