May 2020

JavaScript ES6: The Basics of Classes

JavaScript ES6 Classes are used to set up inheritance and to create objects, and is meant as a solution for JavaScript’s prototypal inheritance. In the examples below you’ll see how messy and complex it is to set up prototypal inheritance and how you can use ES6 Classes to make understanding and implementing inheritance much easier!

The code below is a basic example of how to create objects using a constructor in JavaScript ES5.

//ES5 Basic object creation
// Constructor object
function Car(options) {
  this.title = options.title;
}

// Add a method to the constructor (constructor function)
Car.prototype.drive = function() {
  return 'vroom!';
}

// new keyword on the Car constructor to make a new car
const car = new Car({ title: 'Focus' });

console.log(car); // {"title":"Focus"}
console.log(car.drive); // vroom!

In the code, you’ll see that we are using the ‘prototype’ keyword to create a function on our Car constructor. 

I’m not going to try to explain exactly what the prototype keyword actually does because if you haven’t worked with it much *cough*like me*cough* then it’s difficult to explain. 

So don’t worry about the ‘prototype’ keyword too much as ES6 Classes will be much simpler to get a grasp of.

Let’s expand on the example above by adding an object that will inherit Car so we can set up prototypal linking and then we’ll refactor it using ES6 Classes to show you how much easier it is.

//ES5 Prototypal Inheritance
// Constructor object
function Car(options) {
  this.title = options.title;
}

// Add a method to the constructor (constructor function)
Car.prototype.drive = function() {
  return 'vroom!';
}

// Toyota constructor which will inherit from the Car constructor
function Toyota(options) {
  this.color = options.color;
}

const toyota = new Toyota({ color: 'red', title: 'Daily Driver' });

console.log(toyota); // {"color":"red"}

You’ll see that when we console.log() toyota we only get the color as an output.

Since Toyota is a type of car, we want to set up our Toyota constructor to inherit all the properties and methods of our Car constructor.

// Constructor object
function Car(options) {
  this.title = options.title;
}

// Add a method to the constructor (constructor function)
Car.prototype.drive = function() {
  return 'vroom!';
}

// Toyota constructor which will inherit from the Car constructor
function Toyota(options) {
  // Execute an initialisation that occurs in Car
  Car.call(this, options);
  this.color = options.color;
}
// Duplicate of Car prototype
Toyota.prototype = Object.create(Car.prototype); 

// Add a constructor
Toyota.prototype.constructor = Toyota;

// Now we can add a method to Toyota's prototype
Toyota.prototype.honk = function() {
  return 'beep';
}

const toyota = new Toyota({ color: 'red', title: 'Daily Driver' });

console.log(toyota); // { title, "Daily Driver", color:"red" }
console.log(toyota.honk()); // beep
console.log(toyota.drive()); // vroom

As you might have guessed, writing all that out isn’t fun. There’s so much code for so little functionality, it’s messy, I want it out of my life.

So with ES6 Classes, we’re going to skip having to set up the constructor function, worrying about all the inheritance and writing out the ‘prototype’ keyword all over the place. 

To write a Class, we use the ‘class’ keyword, followed by the name of the class, followed by curly braces. We can then create an instance of that class inside a variable.

// Create the Car class object
class Car {
  // empty 
}

// Create an instance of Car in the car variable.
const car = new Car();

console.log(car); // Car class is empty, so car variable is also empty

Next, to add a method to our class we use the enhanced object literal syntax. That sounds scary but in this case, it’s really just writing a function without the ‘function’ keyword. Let’s recreate our drive method from earlier.

// Create the Car class object
class Car {
  // drive method
  drive() {
      return "vroom";
  }
}

// Create an instance of Car in the car variable.
const car = new Car();

console.log(car.drive()); // vroom

Next, we’re going to do some initialisation within the class. To do this we use a method called ‘constructor()’, which runs whenever we use the ‘new’ keyword on that specific class.

// Create the Car class object
class Car {
  constructor() {
      // I initiate when a new Car() is created!
  }

  drive() {
      return "vroom";
  }
}

// Create an instance of Car in the car variable.
const car = new Car();

We are then going to enter in a title in ‘new Car();’ which will pass title onto the constructor method.

// Create the Car class object
class Car {
  constructor(options) {
      this.title = options.title;
  }

  drive() {
      return "vroom";
  }
}

const car = new Car({ title: 'Toyota' });
console.log(car); // { title:"Toyota" }

Now that we have our Car class set up, we can use the same class syntax we used to create Car to create the Toyota class.

// Create the Car class object
class Car {
  constructor(options) {
      this.title = options.title;
  }

  drive() {
      return "vroom";
  }
}

// Create the Toyota class object
class Toyota {
  constructor(options) {
      this.color = options.color;
  }

  honk() {
      return "beep";
  }
}

// Create an instance of Car in the car variable.
const car = new Car({ title: 'Toyota' });
console.log(car.drive()); // vroom
console.log(car); // { title:"Toyota" }

// Create an instance of Toyota in the toyota variable.
const toyota = new Toyota({ color: 'red' });
console.log(toyota.honk()); // beep
console.log(toyota); // { color:"red" }

Remember, constructor() gets initiated whenever we create a new instance of a class.

Now that Toyota is set up, we want it to inherit the configuration that happens in Car. We’ll also want a separate constructor for Toyota so we can do some custom configuration that we want on Toyota but doesn’t happen in Car.

You’ll remember that in ES5 when setting up inheritance we had to dedicate a few lines to the set up along with the use of a lot of keywords. In ES6, we only have two small additions to make.

On the Toyota class, we simply put ‘class Toyota extends Car’ which will allow Toyota to use all of Car’s methods. 

In Toyota’s constructor(), we’ll call super() to get Car’s properties. So what’s super()? super() calls the constructor of the class that was used after the ‘extends’ keyword. So in our example, super(options) translates to Car.constructor(options).

class Toyota extends Car {
  constructor(options) {
      super(options); // Car.constructor(options)
      this.color = options.color;
  }

  honk() {
      return "beep";
  }
}

And the finished code in its entirety;

//ES6 Classes
// Create the Car class object
class Car {
  constructor(options) {
      this.title = options.title;
  }
    
  drive() {
      return "vroom";
  }
}

// Create the Toyota class object
class Toyota extends Car {
  constructor(options) {
      super(options); // Car.constructor(options)
      this.color = options.color;
  }

  honk() {
      return "beep";
  }
}

// Create an instance of Car in the car variable.
const car = new Car({ title: 'Toyota' });
console.log(car.drive()); // vroom
console.log(car); // { title:"Toyota" }

// Create an instance of Toyota in the toyota variable.
const toyota = new Toyota({ color: 'red', title: 'Daily Driver' });
console.log(toyota.honk()); // beep
console.log(toyota.drive()); // vroom
console.log(toyota); // { title, "Daily Driver", color:"red" }

That’s the basics of JavaScript ES6 Classes! Using two new keywords, ‘class’ and ‘extends’, we can write much cleaner and legible code compared to ES5 where we had to use ‘prototype’.


Continue Reading

  • March 2020

    5 Tips for Staying Productive While Working from Home

    For many of us, myself included, this will be your first experience working away from the office. To help you cope with the change, I've prepared 5 tips for staying productive while working from home.

  • March 2020

    Creating Interactive Accordions using jQuery

    Accordions are useful interface elements that, when clicked, will expand or condense the information on a web page. In this article, I will provide examples on how to create accordions and nested accordions using jQuery, and explain when you might want to use accordions.

  • May 2020

    JavaScript ES6: Template Strings

    Template strings (or template literals) don’t offer much in the way of new functionality but instead make some quality of life improvements to our syntax.

  • January 2018

    Understanding Google PageSpeed Insights

    Google PageSpeed Insights is a useful tool for obtaining information about the speed of your website and offers optimisation suggestions to help improve that speed and helps your site fall in line with optimisation best practices.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now