What are Classes in JavaScript

A brief review

Let's start with a summary of what we have discussed in the past few lessons.

We know that there is a this keyword for JavaScript functions. When used in an object, it refers to the current instance of that object.

javascript
1let user = {
2  name: "John",
3  hi() {
4    console.log(`Hello, ${this.name}!`);
5  },
6};
7
8user.hi();
text
1Hello, John!

Unlike the this keyword in other programming languages, JavaScript allows this to exist outside of an object, which enables us to build constructor functions like this:

javascript
1function User(name) {
2  this.name = name;
3  this.hi = function () {
4    console.log(`Hello, ${this.name}!`);
5  };
6}
7
8let user = new User("John");
9
10console.log(user.name);
11user.hi();
text
1John
2Hello, John!

Constructor functions are used to programmatically create objects. You can create both properties and methods with a constructor function.

There are two special properties in objects called getters and setters. As the name suggests, they are used to get or set property values.

javascript
1let user = {
2  firstName: "John",
3  lastName: "Doe",
4
5  get name() {
6    return `${this.firstName} ${this.lastName}`;
7  },
8
9  set name(name) {
10    [this.firstName, this.lastName] = name.split(" ");
11  },
12};
13
14console.log(user.name);
15
16user.name = "Alice Cooper";
17
18console.log(user.name);
text
1John Doe
2Alice Cooper

You can create an inheritance system using objects by setting an object to be the prototype of another object, which can be the prototype of another object, and so on.

javascript
1let user = {
2  . . .
3};
4
5let admin = {
6  role: "Admin",
7};
8
9Object.setPrototypeOf(admin, user);
10
11let profile = {
12  created: "2022-09-01",
13};
14
15Object.setPrototypeOf(profile, admin);

All of these concepts we have discussed so far in the past few lessons belong to a programming paradigm called object-oriented programming, where you divide the program into reusable pieces in the form of objects.

And because this programming paradigm is so popular, JavaScript offers a more standard syntax called the class notation.

Using the standard class syntax

Instead of a separate constructor function, you can define a class using the class keyword, and inside that class, create a constructor() function. Again, it is conventional for classes to be named with uppercase letters.

javascript
1class User {
2  constructor(firstName, lastName) {
3    this.firstName = firstName;
4    this.lastName = lastName;
5  }
6}

To call this constructor() function, use the same keyword new, and the class name.

javascript
1let user = new User("John", "Doe");
2
3console.log(user);
text
1User { firstName: 'John', lastName: 'Doe' }

To create methods, instead of putting them inside the constructor() function, they are placed at the same level as the constructor().

javascript
1class User {
2  constructor(firstName, lastName) {
3    this.firstName = firstName;
4    this.lastName = lastName;
5  }
6
7  printFullName() {
8    console.log(`${this.firstName} ${this.lastName}`);
9  }
10}
11
12let user = new User("John", "Doe");
13
14user.printFullName();
text
1John Doe

What is a class

So, what exactly is a class? In JavaScript, class is a function. It is not a language-level entity. It is just a syntax sweetener for creating constructor functions. You can verify this using the typeof operator.

javascript
1class User {
2  constructor(firstName, lastName) {
3    this.firstName = firstName;
4    this.lastName = lastName;
5  }
6}
7
8console.log(typeof User);
text
1function

When you define a class, let's say User, JavaScript will create a constructor function internally, and the corresponding properties will be created based on the information provided in the constructor().

The methods, on the other hand, will be stored in User.prototype. When you call a method under User, that method is actually taken from prototype. This can be verified with the following example.

javascript
1class User {
2  constructor(firstName, lastName) {
3    this.firstName = firstName;
4    this.lastName = lastName;
5  }
6
7  example() {
8    console.log("This method in in the prototype.");
9  }
10}
11
12User.prototype.example();
text
1This method in in the prototype.

Just like a regular function, the classes can be assigned to a variable, passed as an argument, returned as an output, and more.

javascript
1let User = class {
2  constructor(firstName, lastName) {
3    this.firstName = firstName;
4    this.lastName = lastName;
5  }
6
7  example() {
8    console.log("This method in in the prototype.");
9  }
10};
11
12let user = new User("John", "Doe");
javascript
1function createUserClass() {
2  return class {
3    constructor(firstName, lastName) {
4      this.firstName = firstName;
5      this.lastName = lastName;
6    }
7
8    example() {
9      console.log("This method in in the prototype.");
10    }
11  };
12}
13
14let User = createUserClass();
15
16let user = new User("John", "Doe");

Getters and setters

The getters and setters in the class are created in a similar way.

javascript
1let User = class {
2  constructor(name) {
3    // Invoking the setter
4    this.name = name;
5
6    // These fields will be filled by the setter
7    this.firstName;
8    this.lastName;
9  }
10
11  get name() {
12    return `${this.firstName} ${this.lastName}`;
13  }
14
15  set name(name) {
16    [this.firstName, this.lastName] = name.split(" ");
17  }
18};
19
20let user = new User("John Doe");
21
22console.log(user);
text
1User { firstName: 'John', lastName: 'Doe' }