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 work with arrow functions and classes.
Use Arrow Functions for Anonymous Functions
Arrow functions should be used for anonymous functions.
This way, we don’t have to deal with different values of this
, and it’s shorter.
For instance, instead of writing:
[1, 2, 3].map(function (x) {
return x + 1;
});
We write:
[1, 2, 3].map((x) => x + 1);
It’s much shorter and the value of this
is the same as the outside.
Remove Curly Braces for Arrow Functions that are one Statement Long
We don’t need curly braces for arrow functions that are one statement long.
For instance, we can write:
[1, 2, 3].map((x) => x ** 2);
The return is implicit so we also don’t need to write return
.
If an Expression Spans Multiple Lines, Wrap it in Parentheses
If we have an arrow function that’s one statement long, then we’ve to wrap it in parentheses so that we can return the whole expression.
For instance, we can write:
[1, 2, 3].map((x) => ({
[x]: x
}));
This way, we map each array entry with the key and value set to the array entry’s value.
We can do that for any long expressions.
Include Parentheses Around Arguments for Clarity and Consistency
Adding parentheses around arguments make our arrow function signature clearer.
It’s also consistent with arrow functions that make no arguments or multiple arguments.
For instance, we write:
[1, 2, 3].map((x) => x ** x);
instead of:
[1, 2, 3].map(x => x ** x);
Avoid Confusing Arrow Function Syntax with Comparison Operators
We should put parentheses around comparison expressions so that we know that they’re comparison expressions.
For instance, instead of writing:
[1, 2, 3].map((x) => x <= 2);
We write:
[1, 2, 3].map((x) => (x <= 2));
As we can see omitting the parentheses make our arrow function much harder to read.
Classes & Constructors
We should embrace modern syntax instead of using old syntax.
Use class Syntax Instead of prototype
Using the class syntax makes things clearer than manipulating prototype properties.
Prototypes are something that many people are confused about.
To add instance methods to a constructor, instead of writing:
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}
We write:
class Person {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Instead of adding methods to the prototype
property, we should put methods inside a class instead.
Instance variables should be initialized in the constructor
method instead of a constructor function.
After a class is declared with the given, we can’t declare another one with the same name.
That isn’t the case with constructors.
Use extends for Inheritance
extends
with the class syntax makes inheritance much easier.
Also, instanceof
will work properly.
For instance, instead of writing:
function Animal(name) {
this.name = name;
}
Animal.prototype.getName = function() {
return this.name;
}
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Animal;
We should write:
class Animal {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
}
Now when we create a Dog
instance, we can use instanceof
to check if it’s an instance of Animal
.
We can write:
const dog = new Dog();
console.log(dog instanceof Animal)
to see that the console log shows true
so inheritance is done correctly.
The constructor function syntax gives us the same result but the process is more complex and error-prone.
Methods can Return this
to Help with Method Chaining
In classes, we can have methods that return this
to let us chain them.
For instance, we can write:
class Cube {
setLength(val) {
this.length = val;
return this;
}
setWidth(val) {
this.width = val;
return this;
}
setHeight(val) {
this.height = val;
return this;
}
}
Then we can chain methods of the Cube
instance by writing:
const cube = new Cube()
.setHeight(10)
.setWidth(20)
.setLength(30)
And cube
is {height: 10, width: 20, length: 30}
Conclusion
The class syntax and arrow functions are 2 of the best features of JavaScript, so we should use them as much as possible.