Classes in JavaScript Explained – What Is a JavaScript Class?
A JavaScript class is an object constructor that the new
keyword uses to create a new object instance.
Example of a JavaScript Class
The snippet above used the new
keyword to create a new object instance from the class constructor.
Why Classes in JavaScript?
Classes provide a way to create a template for creating objects that have access to private data through public methods.
In other words, classes help you encapsulate your data while providing users indirect access to an instance’s internal workings. This helps you provide users with a clean and friendly interface that is independent of an object’s internal implementations.
For instance, Date
is a JavaScript class that allows you to access its date data through its public methods, such as getDate()
, setDate()
, and getFullYear()
.
Syntax of a JavaScript Class
A class is composed of four components:
- A
class
keyword - The class’s name
- A code block (
{...}
) - The class’s body
Types of JavaScript Classes
The three types of JavaScript classes are:
- Class declaration
- Class expression
- Derived class
Let’s discuss each type.
What is a JavaScript class declaration?
A class declaration is a class created without assigning it to a variable.
Here’s an example:
The class above is a class declaration because we defined it without storing it in a variable.
What is a JavaScript class expression?
A class expression is a class you create and assign to a variable.
Here’s an example:
The class above is a named class expression that we assigned to the myClassExpr
variable.
You can also write the snippet above as an anonymous class expression like so:
The class above is an anonymous function expression assigned to the myClassExpr
variable.
Let’s now discuss derived classes.
What is a derived class in JavaScript?
A derived class is a class that extends the public and static features of an existing class.
In other words, a derived class is the child of a parent class.
Syntax of a derived class
We use the extends
keyword to create a derived class.
Here’s the syntax:
Once you extend a child class to a parent class, the derived class will inherit all its base class’s class fields.
Example: How to use a base class’s features in a derived class
The Bio
class inherited its parent’s property because we used the extends
keyword to assign the Name
class as the derived class’s dunder proto.
Note: A derived class’s class field will override its parent class’s property with the same name. For example, consider the following code:
Now that we know the syntax and types of JavaScript classes let’s look at the main components in one piece.
Components of a JavaScript Class
The main features of a JavaScript class are as follows:
- A
class
keyword - The class’s name
- The
extends
clause - A code block (
{...}
) - The class’s body
- A
constructor
method super()
function callersuper
property accessor- Instance class fields
- Prototypal class fields
- Private class fields
- Static class fields
- Static initialization blocks
Let’s look at these features in a class declaration.
The constructor function equivalence of the snippet above looks like this:
How Does a JavaScript Class Help with Encapsulation?
Classes let you prevent external code from interacting with internal class fields. Instead, external code would use public methods to operate on the class’s internal implementations.
For instance, consider the following code:
The snippet above encapsulated Name
’s data because it defined myName
as a private feature and provided two public methods for users to read and update the class’s internal implementation.
Consequently, the bio
instance object knows nothing about the class’s internal data and cannot interact with it directly.
Whenever users need to access the encapsulated data, they would use the publicly available methods like so:
Encapsulating your data is an excellent way to keep your class clean. It prevents minor internal refactoring from breaking users’ code.
For instance, consider the following code:
Since the snippet above did not encapsulate the class’s data, refactoring the class field’s name would break users’ code.
Here’s an example:
The snippet above returned undefined
because refactoring the class’s internal implementation broke the user’s bio.myName
code. For the application to work appropriately, the user must update every instance of the code (which can be burdensome for large projects).
However, encapsulation prevents such refactoring from breaking the user’s code.
Here’s an example:
You can see that refactoring the class’s internal implementation did not break the user’s code. That’s the beauty of encapsulation!
Encapsulation allows you to provide users with an interface independent of the class’s underlying data. Therefore, you minimize the likelihood of users’ code breaking when you alter internal implementations.
Learn CSS Grid with Images
Important Stuff to Know about JavaScript Classes
Here are five essential facts to remember when using JavaScript classes.
1. Declare your class before you access it
Classes are like constructor functions but have the same temporal dead zone behavior as const
and let
variables.
In other words, JavaScript does not hoist class declarations. Therefore, you must first declare your class before you can access it. Otherwise, the computer will throw an Uncaught ReferenceError
.
Here’s an example:
The snippet above throws an Uncaught ReferenceError
because JavaScript does not hoist classes. So, invoking Name()
before its definition is invalid.
2. Classes are functions
The typeof
a class is a function because, under the hood, the class
keyword creates a new function.
For instance, consider the following code:
The computer processes the snippet above like so:
- Create a new function named
Bio
. - Add the class’s instance properties to the newly created function’s
this
keyword. - Add the class’s prototypal properties to the newly created function’s
prototype
property.
3. Classes are strict
JavaScript executes classes in strict mode. So, follow the strict syntax rules when you use classes. Otherwise, your code will throw errors—some of which will be silent errors that are difficult to debug.
4. Avoid the return
keyword in your class’s constructor
method
Suppose your class’s constructor
returns a non-primitive value. In that case, JavaScript will ignore the values of all the this
keywords and assign the non-primitive to the new
keyword expression.
In other words, a constructor’s return
ed object overrides its keyword this
.
For instance, consider the following code:
The new
keyword expression returned only { companyName: "CodeSweetly" }
because JavaScript ignores the constructor method’s this
keywords whenever you use a return
operator to produce an object.
5. A class’s evaluation starts from the extends
clause to its values
JavaScript evaluates your class according to the following order:
1. extends
clause
If you declare an extends
clause, the computer will first evaluate it.
2. Extract the class’s constructor
JavaScript extracts the class’s constructor
.
3. Parse the class’s property names
The computer analyzes the class’s class field names (not their values) according to their order of declaration.
4. Parse the class’s methods and property accessors
JavaScript analyzes the class’s methods and property accessors according to their order of declaration by doing the following:
- Add the prototypal methods and property accessors to the class’s
prototype
property. - Analyze the static methods and property accessors as the class’s own properties, which you can call on the class itself.
- Analyze the private instance methods and property accessors as private properties of the class’s instance object.
5. Parse the class’s property values
The computer analyzes the class’s class field values according to their order of declaration by doing the following:
- Save each instance field’s initializer expression for later evaluations. JavaScript will evaluate the initializer expression during the following periods:
- When the
new
keyword is creating an instance object. - While processing the parent class’s constructor.
- Before the
super()
function call returns.
- When the
- Set each static field’s keyword
this
to the class itself and create the static property on the class. - Evaluate the class’s static initialization blocks and set their keyword
this
to the class itself.