JavaScript, like any other programming language, has many handy tricks that let us write our programs more easily.
In this article, we will look at how to remove duplicate elements, remove falsy values from arrays, create empty objects, and check for required function parameters.
Remove Duplicate Elements
Before ES6, removing duplicate elements from an array was a pain. We had to check if each one exists and, if it already exists, then we remove the entry that duplicates the same one in another place that already exists.
Another way was to make a dictionary that had the array entries as the key and then loop through the dictionary’s key to create another array.
With ES6, we don’t have to do this anymore since we have a new iterable object called Sets
. It’s exactly what it sounds like, in that it represents a set as it does in mathematics.
A Set
in math is a collection of things that can’t have duplicates. With the Set
constructor, we can pass in an array straight into the Set
constructor to create a set.
For example, if we have an array that has duplicate elements then we can convert it to a Set
and back into an array. For example, we can write:
let arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
const set = new Set(arr);
arr = Array.from(set);
console.log(arr);
In the code above, we have an array of numbers arr
that has many duplicate entries. To remove the duplicate elements, we first create a Set
with the arr
array.
Then, we convert it back to an array with the Array.from
method which takes any array like object as a valid argument and then we assigned it back to arr
.
That way, we use the same variable for the array, but all the duplicate elements are gone. If we run the console.log
statement in the code above, we get [1, 2, 3, 4, 5]
back.
Alternatively, we can replace the Array.from
method with the spread operator since a Set
is an iterable object, which means that it works with the spread operator. We can write the code above like the following:
let arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
const set = new Set(arr);
arr = [...set]
console.log(arr);
If we run the code above, we should get the same console.log
output as the first example. To make it even shorter, we don’t even have to create the set
variable, rather, we just use the spread operator, like in the following code:
let arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5];
arr = [...new Set(arr)];
console.log(arr);
This is even shorter and uses less memory since we don’t have to create another variable just to remove duplicate elements. With the spread operator, now we don’t need a loop just for removing duplicate elements from an array.
Remove Falsy Values
To remove falsy values like 0
, undefined
, null
, NaN
, or false
from an array, we can call the Boolean
method to do this, since the Boolean
will convert falsy values to the boolean value false
.
We can remove those values, like in the following code:
let arr = [1, 2, 3, 4, 5, 6, false, null, undefined, , null, NaN, 0];
arr = arr.filter(a => Boolean(a));
console.log(arr);
In the code above, we have an array arr
with some numbers and falsy values, like false
, null
, undefined
, NaN
, and 0
in the array as well as a whole in the middle of the array which is interpreted as undefined
.
We filter them out by using the Boolean
factory function which returns the truth value of these values. The falsy ones are converted to false
which are then a new array. With the falsy values removed it returns the filter
function.
Then the returned array is assigned back to the arr
variable, which makes the arr
array take on the new value with the array with the falsy values removed. In the end, we get the console.log
output [1, 2, 3, 4, 5, 6]
.
Since the Boolean
function takes in one argument, which is the value that you want to convert to a boolean, and that matches the signature of the callback function that we pass into the filter
method, we can make this even shorter by passing in the Boolean
function straight into the filter
method as its callback function like in the following code:
let arr = [1, 2, 3, 4, 5, 6, false, null, undefined, , null, NaN, 0];
arr = arr.filter(Boolean);
console.log(arr);
With the code above, we should get the same output from the console.log
as we have above. Note that we remove the parentheses from the Boolean
function.
This is because we are passing in the function reference to the filter
method as its callback function. If we pass in a reference to a function as an argument of another function, then we shouldn’t include the parentheses as we aren’t calling the function, we just want to pass in the function reference.
Create Empty Objects
If we want to create a pure empty object without any prototype, we shouldn’t be using the {}
literal since this will create an object with the prototype type. If we run:
console.log({}.__proto__)
Or:
console.log(Object.getPrototypeOf({}))
We get stuff like:
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
As the output. As we can see, there’s already a bunch of methods that are inherited from the {}
’s prototype.
If we don’t want those methods, we can create an object without any prototype by passing in null
into the Object.create
method like in the following code:
const obj = Object.create(null);
console.log(obj.__proto__);
console.log(Object.getPrototypeOf(obj))
The code above will create an object without a prototype, which is why we passed in null
into the argument of the Object.create
method.
If we run the first console.log
statement above, we should get undefined
, and for the second one, we should get null
.
Check for Required Parameters
With ES6, we can set default values of function parameters in the function signature. We can set a value as the default parameter or we can set the return value of another function as the default parameter.
This means that we can run another function as we’re calling a function that takes arguments. We can use this to check for required values by assigning the default value of a parameter with a function call.
For example, we can write the following code:
const checkRequired = (paramName) => {
throw new Error(`${paramName} is required`);
};
const greet = (name = checkRequired('name'), greeting = checkRequired('greeting')) => {
console.log(`Hello ${name}, ${greeting}`)
};
greet('Jane', 'How are you?');
try {
greet('Jane');
} catch (error) {
console.log(error);
}
try {
greet('How are you?');
} catch (error) {
console.log(error);
}
try {
greet();
} catch (error) {
console.log(error);
}
Then, we should get something like this:
Hello Jane, How are you?
Error: greeting is required
at checkRequired ((index):33)
at greet ((index):36)
at window.onload ((index):42)
Error: greeting is required
at checkRequired ((index):33)
at greet ((index):36)
at window.onload ((index):48)
Error: name is required
at checkRequired ((index):33)
at greet ((index):36)
at window.onload ((index):54)
As the output from the console.log
statements.
What we were doing with the code above is that we are running the checkRequired
function as we’re calling the greet
function with the given arguments.
With each function call, we run the checkRequired
function as each argument is being passed into the parameters if the argument is undefined
or omitted as we set the return value of the checkRequired
function to be the default value of the parameters if the argument is omitted or undefined
is passed in.
It doesn’t matter what the return of checkRequired
is. We just want it to run if the argument value is omitted or it’s undefined
. This way, the greeting
function won’t run if both arguments aren’t passed in.
JavaScript, like any other programming language, has many handy tricks that let us write our programs more easily.
In this article, we looked at how to remove duplicate elements, remove falsy values from arrays, create empty objects, and check for required function parameters.
With these tricks, we reduce the effort we put into writing our code, making our lives easier.