Object-Oriented JavaScript — Class Basics

John Au-Yeung - Jan 24 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at the basics of classes.

Classes

ES6 brings many useful features that helps us create objects more easily.

If we’re familiar with class-based languages like Java, then JavaScript classes should look familiar.

But JavaScript classes are syntactic sugar over its prototypical inheritance model.

Before ES6, we can only create constructors.

function Person(name) {
  if (!(this instanceof Person)) {
    throw new Error("Person is a constructor");
  }
  this.name = name;
};

Person.prototype.eat = function() {
  //...
};
Enter fullscreen mode Exit fullscreen mode

We have the Person constrictor with the this.name instance property.

And Person.prototype.eat is an instance method.

Then we can create a child constructor that inherits from the Person constructor by writing:

function Employee(name, job) {
  if (!(this instanceof Employee)) {
    throw new Error("Employee is a constructor");
  }
  Person.call(this, name);
  this.job = job;
};

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.work = function() {
  // ...
};
Enter fullscreen mode Exit fullscreen mode

We create the Employee constructor that calls the Person constructor with the name argument.

Then we set this.job to job .

And then we create the prototype of Employee with Object.create .

We inherit the properties of the Person.prototype since we used the Object.create method with Person.prototype as the argument.

Then we can create our methods and set the constructor to Employee so using instanceof on an Employee instance would return true .

With the class syntax, we can make our lives much easier:

class Person {
  constructor(name) {
    this.name = name;
  }

  eat() {
    //...
  }
}

class Employee extends Person {
  constructor(name, job) {
    super(name);
    this.job = job;
  }

  work() {
    //...
  }
}
Enter fullscreen mode Exit fullscreen mode

We create the Person class.

The constructor method has what was in the constructor function itself.

The prototype methods are in the class.

To create a child class, we use the extends keyword and then call super to call the Person constructor.

Then we have the work instance method.

The eat method is inherited from the Person instance also.

Defining Classes

We can define classes with the class keyword.

It’s very similar to class-based languages like Java or C#.

For instance, we can write:

class Car {
  constructor(model, year) {
    this.model = model;
    this.year = year;
  }
}
Enter fullscreen mode Exit fullscreen mode

The Car class is still a function.

So if we log:

console.log(typeof Car);
Enter fullscreen mode Exit fullscreen mode

we see 'function' .

Classes are different from normal functions.

They aren’t hoisted.

Normal functions can be declared anywhere in the scope and it’ll be available.

But classes can only be accessed if they’re defined.

So we can’t write:

const toyota = new Car();
class Car {}
Enter fullscreen mode Exit fullscreen mode

because we’ll get the reference error:

Uncaught ReferenceError: Cannot access 'Car' before initialization
Enter fullscreen mode Exit fullscreen mode

We can’t use commas while separating the members of a class, but we can add semicolons.

So we can’t write:

class C {
  member,
  method() {}
}
Enter fullscreen mode Exit fullscreen mode

we’ll get a syntax error.

But we can write:

class C {
  method2() {};
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

The class syntax makes creating constructors easier.

We can do inheritance with extends and super .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .