JavaScript is a very flexible language. There’s a lot of things in JavaScript that we probably shouldn’t write. Old constructs that aren’t good coexist with new constructures that are better.
In this article, we’ll look at some good parts of JavaScript that we should use regularly.
Don’t Use var, Use let or const
var
is an outdated keyword for declaring variables. Instead, we should use let
and const
. let
and const
are both block-scoped, so that we can use them without worrying about clashing scopes as long as they’re in a block.
For instance, we can write the following:
let x = 1;
const y = 2;
instead of:
var x = 1;
var y = 2;
const
also have the advantage that we can’t reassign a new value to it. However, it doesn’t make an object immutable.
Use === or Object.is
Instead of ==
==
saves one character of typing, but the rules for comparing with ==
is complex and hard to remember. It also produces lots of unexpected results. Therefore, we shouldn’t use ==
.
For instance, the following both return true
:
[10] == 10
'10' == 10
We probably don’t want that. Therefore, we should write the following instead:
[10] === 10
'10' === 10
Then they both return false
since the data type and value of both operands have to match in order for the ===
to consider them the same. However, NaN === NaN
returns false
.
To check for NaN
, we should use the isNaN
function, which tries to convert its argument to a number and check against that. Therefore, isNaN(‘NaN’)
and isNaN(NaN)
both return true
.
There’s also the Number.isNaN
function, which doesn’t do any conversion when checking. Therefore, Number.isNaN(‘NaN’)
returns false
and Number.isNaN(NaN)
returns true
.
There’s also the Object.is
method, which does the same thing as ===
ecept that NaN
is the same as itself.
We can use that as follows:
Object.is('foo', 'bar')
The arguments are the 2 things that we want to compare.
undefined, null, 0, false, NaN, ‘’ (empty string) are all Falsy.
We have to remember these since they all return false
when we try to convert them to boolean with !!
or Boolean
.
Use Semicolons for Line Termination
JavaScript is forgiving in that it doesn’t need semicolons for terminating lines. It’ll just insert the semicolons after line breaks or wherever it thinks it can end the line.
However, this will produce unexpected results. For instance:
const foo = () => {
return
{
first: 'john'
};
}
will return undefined
because the semicolon is added after return
, so the code below it is never run.
Therefore, we should insert semicolons as needed to clarify where a line ends.
Use Class Syntax for Object Constructors
In JavaScript, classes are the same as object constructore functions. However, the syntax is stricter so that it’s harder to make mistakes, especially when we need to do inheritance. For instance, we can write the following class:
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
which is the same as:
function Person(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
}
It’s just that the class
syntax is more conventional syntax, especially for people who worked with other object-oriented languages.
It makes even more sense if we have methods. For instance, with the class syntax, we write:
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
fullName() {
return `${this.firstName } ${this.lastName }`;
}
}
The Person
class above has the fullName
method. On the other hand, with the old constructor function syntax, we write:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullName = function() {
return `${this.firstName } ${this.lastName }`;
}
This just doesn’t make as much sense for many developers, especially for non-JavaScript developers.
The class syntax makes things much clearer. The class syntax makes even more sense with inheritance. With the old syntax, we write:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.fullName = function() {
return `${this.firstName } ${this.lastName }`;
}
function Student(studentId) {
Person.call(this, studentId);
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Person;
There’re no errors if we missed anything when we write the code above.
However, with the class syntax, we write:
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
fullName() {
return `${this.firstName } ${this.lastName }`;
}
}
class Student extends Person {
constructor(firstName, lastName, studentId) {
super(firstName, lastName);
this.studentId = studentId;
}
}
We’ll also get errors if we didn’t follow the syntax like forgetting to call super
when we have extends
.
Conclusion
There’re a few important things we should use to write JavaScript code, including ===
instead of ==
, class syntax instead of constructor functions and prototype, use let
and const
instead of var
to declare variables and constants, and remember falsy values