Javascript constructor and inheritance: build your own data structure

This tutorial is a part of the Learn everything about Javascript in one course.

Purpose to create object blueprint with "object function" and "class"

Purpose: to create your own data structure including the properties and methods. For example, you can create your own Array data structure like Javascript built-in Array. You can do it in two ways:

  • Using object function (we have learnt about object function).
  • Using class (available from ES6).

class and object function:

  • are "blueprint creator".
  • have formal name as constructor in Javascript.
  • we always use the new operator in front of a constructor to create and instance of that blueprint.

We will focus on class in this tutorial as we have we have learnt about object function previously.

Create object blueprint using "class"

The constructor method in class declaration:

  • is optional and special.
  • is run when object instantiation happens.
  • is used frequently in practice to setup initial conditions of object.

The this keyword in class declaration refers to the class itself.

class.js
// Create object blueprint with "class"

// create Car blueprint (class)
class Car {
  constructor(make, year) { // "make", "year" are arguments accepted at instantiation
    this.make = make // define class property "make"
    this.year = year // define class property "year"
  }

  powerBy = 'electricity' // another way to define class property "powerBy"
  #mileage = 500000 // define a "private" property "mileage" (only accessible within class)

  honk() { // define a synchronous method
    console.log('beep beep!')
  }

  getMileage() { // define another synchronous method
    console.log('car mileage:', this.#mileage)
  }

  async charge() { // define a asynchronous method
    console.log('charging...')
    setTimeout(() => {
      console.log('charging complete!')
    }, 1000)
  }
}

// create car1 object based on Car blueprint
const car1 = new Car('Tesla', 2020) // car1 is an instance of "blueprint" Car
console.log(car1.make) // Tesla
console.log(car1.year) // 2020
console.log(car1.powerBy) // electricity
console.log(car1.mileage) // undefined, private property, can't access from outside
car1.getMileage() // car mileage: 500000, inside function can access private property
car1.honk() // beep beep!
car1.charge()
// charging...

// create car2 object based on Car blueprint
const car2 = new Car('Bat Mobile', 2051) // car2 is another instance of "blueprint" Car
console.log(car2.make) // Bat Mobile
console.log(car2.year) // 2051

// charging complete!

Create new blueprint based on another blueprint with "extends"

We can build new blueprint (child class) based on existing blueprint (parent class) by using class and extends keyword. The super keyword used in the child class:

  • is used to call parent class's methods.
  • super() calls parent class constructor method (this is special).
  • super.parentMethodName() calls parent class's method named parentMethodName.
class_extends_super.js
// create new blueprint "Supercar" based on blueprint "Car"
class Supercar extends Car {
  constructor() {
    super(...arguments) // calls "Car" constructor method
    super.getMileage() // call "Car" getMileage method
    // here we can extend class Car further
    // with any setup we want
  }

  topSpeed = '250 mph' // add new property for "Supercar" class

  race() { // new method for Supercar
    console.log('racing with top speed', this.topSpeed)
  }
}

const sup1 = new Supercar('Bugatti', 2020) // car mileage: 500000
console.log(sup1.make) // Bugatti, parent's property
console.log(sup1.year) // 2020, parent's property
sup1.honk() // beep beep!, parent's method
console.log(sup1.topSpeed) // 250 mph, Supercar's property
sup1.race() // racing with top speed 250 mph, Supercar's method

Enhance object function blueprint with "prototype"

We can add more property and method to object function blueprint after defining it. Syntax ObjectFunction.prototype.newPropertyOrMethod.

object_function_prototype.js
// Create object blueprint using "object function"

// this blueprint is equivalent to the one create with "class" above
function Car(make, year) {
  this.make = make
  this.year = year
  this.powerBy = 'electricity'

  const mileage = 500000

  this.honk = () => console.log('beep beep!')

  this.getMileage = () => console.log('car mileage:', mileage)

  this.charge = async () => {
    console.log('charging...')
    setTimeout(() => {
      console.log('charging complete!')
    }, 1000)
  }

}

const car1 = new Car('Tesla', 2020) // car1 is an instance of "blueprint" Car
console.log(car1.make) // Tesla
console.log(car1.year) // 2020
console.log(car1.powerBy) // electricity
console.log(car1.mileage) // undefined, private property, can't access from outside
car1.getMileage() // car mileage: 500000, inside funciton can access private property
car1.honk() // beep beep!
car1.charge() // charging...
// charging complete!

// add more property to Car blueprint
Car.prototype.type = 'Green Vehicle'
console.log(car1.type) // Green Vehicle

const car2 = new Car() // "prototype" applies to existing and newly created object
console.log(car2.type) // Green Vehicle

// add more method to Car blueprint
Car.prototype.selfDrive = () => console.log('self driving activated')
car1.selfDrive() // self driving activated
car2.selfDrive() // self driving activated

Summary

  • Object function and class can both be used to declare object blueprint. Object function and class are also called constructor.
  • The action of creating a new object based on a blueprint is call instantiation. The newly created object is called an instance of the blueprint.
  • We can use extends to create a new blueprint based on an existing blueprint.
  • We can use prototype to add more properties and methods for existing Object function blueprint.
  • Knowledge in this tutorial is also collectively called as class and inheritance.