Classes
— Ancient Chinese proverb
Defining Classes
Instead of manually constructing objects, you can also use classes. We will not write our own classes in this book since we adopt a functional style, so we will keep this section as brief as possible.
Nevertheless, you still have to roughly understand what a class is in order to use the pre-built classes like Error
or Map
that we will discuss in the following sections.
At its core, classes are templates for creating objects.
For example, you could define a Task
class that would serve as a template for creating new task objects like this:
class Task {
constructor(id, title, description) {
this.id = id;
this.title = title;
this.description = description;
}
}
Note the presence of the special constructor
method.
This method allows you to initialize the newly created object with some values.
Specifically, you can construct a task object from the Task
class using the new
operator:
const task = new Task(1, 'Read the Next.js book', 'Read and understand the Next.js book.');
If an object is constructed from a class X
, we often say that the object is an instance of X
or just an X
object.
For example, task
would be an instance of the Task
class or just a Task
object.
You can then access the instance properties as you normally would:
console.log(task.id); // 1
console.log(task.title); // Read the Next.js book
console.log(task.description); // Read and understand the Next.js book.
Another important keyword for working with classes is the this
keyword which allows you to point to the current instance of the class you're working with.
Put simply, this
is a reference to the current object.
Therefore, when we write this.id = id
in the constructor, we want to initialize the id
of the current object with the id
that was passed as an argument to the constructor.
The this
keyword is particularly important in the context of instance methods.
Instance Methods
An instance method (often just method for short) is a function which is a property of an object. Here is a simple example:
const greeter = {
greet: function () {
console.log('Hello, World!');
},
};
You can call a method like this:
greeter.greet(); // Hello, World!
Just like constructors, methods can refer to the properties of an object using the this
keyword:
const task = {
id: 1,
title: 'Read the Next.js book',
description: 'Read and understand the Next.js book.',
longDescription: function () {
return `${this.title}(ID = ${this.id}): ${this.description}`;
},
};
You can call the method by writing task.longDescription()
.
This would output:
Read the Next.js book(ID = 1): Read and understand the Next.js book.
We can also define instance methods for an entire class. In that case, the instance method is available for all objects of that class.
For example, we could write an instance method that creates a short task description by combining the ID and title of a task like this:
class Task {
constructor(id, title, description) {
this.id = id;
this.title = title;
this.description = description;
}
getShortDescription() {
return `Task ${this.id} (${this.title})`;
}
}
Let's now construct two tasks:
const task1 = new Task(1, 'Read the Next.js book', 'Read and understand the Next.js book.');
const task2 = new Task(2, 'Write a task app', 'Write an awesome task app.');
We can now log the short description of the first task:
console.log(task1.getShortDescription());
This will log:
Task 1 (Read the Next.js book)
Similarly, we can log the short description of the second task:
console.log(task2.getShortDescription());
This will log:
Task 2 (Write a task app)
Note how getShortDescription
is available for both task1
and task2
.
But how does this work?
Put differently, how does getShortDescription
know whether it should refer to task1
or task2
?
The answer lies in the this
keyword.
In the case of task1.getShortDescription()
, this
will refer to task1
and so the function will access task1.id
and task1.title
.
However, in the case of task2.getShortDescription()
, this
will refer to task2
and so the function will access task2.id
and task2.title
.
Static Methods
Static methods are methods that can't be accessed on instances of a class, but must be accessed directly on the class itself.
For example, you can use Number.parseInt
to parse a string argument:
console.log(Number.parseInt('123')); // 123
Static methods will become important in a few sections, when we introduce a few useful static methods that deal with arrays and objects.