Custom Class Objects

Constructor Functions and "new"

Todd Motto by Todd Motto Google Developer Expert Icon Google Developer Expert
JavaScript Icon

Learn JavaScript the right way

Premium JavaScript courses to skyrocket your skills to the top.

5x Courses: Basics, Masterclass, HTML5 APIs, DOM, Testing with Jest.

Constructor functions are part of the Object-Oriented Programming (OOP) paradigm, and allow us to encapsulate behavior into “classes”.

In JavaScript, there are built-in constructor functions:

new Object();
new Array();
new String();
new Number();
new Boolean();

…and a few others. Every instance created from a constructor function is fully unique.

This is a critical concept to grasp and is essential for creating well-designed and reusable units of code - often referred to as “classes”.

An instance is a brand new version of our constructor.

Custom constructor functions allow us to model our data and how it’s interacted with.

They begin with a simple function:

function Drink() {}

The capitalization of “Drink” is a common naming convention when creating custom constructors, as it follows the style of built-in JavaScript constructors.

To allow us to use this function as a custom object, it must be called with new:

new Drink();

This design pattern requires us to then bind properties and methods to the function’s this:

function Drink(name, price) {
  this.name = name;
  this.price = price;
}

Anything attached to this is made publicly available.

So now when we call our constructor, we see our custom object:

const lemonade = new Drink('Lemonade', 299);

// Drink { name: 'Lemonade', price: 299 }
console.log(lemonade);

We can check if it’s our custom object in the following ways too:

const lemonade = new Drink('Lemonade', 299); 

console.log(lemonade.constructor); // ƒ Drink
console.log(lemonade instanceof Drink); // true

We can check the prototype property of objects to see “what made them”.

And also use the instanceof operator, which tells you if your object is an “instance of” something else.

Methods can also be attached inside the constructor in the same way properties can:

function Drink(name, price) {
  this.name = name;
  this.price = price;
  this.getName = function() {
    return this.name;
  };
}

We can then use the constructor as many times as needed:

const lemonade = new Drink('Lemonade', 299);
const coffee = new Drink('Coffee', 399);

lemonade.getName(); // Lemonade
coffee.getName(); // Coffee

See how each constructor call creates a unique instance? This creates powerful data modelling.

The properties and methods are “attached” to each custom object.

As object creation is deemed “expensive”, a common pattern is to attach methods to the prototype of a constructor:

function Drink(name, price) {
  this.name = name;
  this.price = price;
}

Drink.prototype.getName = function() {
  return this.name;
};

This behaves identically to the previous example, but offers an inheritance model that is far faster to create.

Last but not least, let’s discuss the newer addition to JavaScript - the class keyword.

This is just syntax sugar for everything you’ve learned above and offers the same functionality.

Moving our existing logic into a class allows us to create more modern style code whilst keeping things neat, clear and concise:

class Drink {
  constructor(name, price) {
    this.name = name;
    this.price = price;
  }
  getName() {
    return this.name;
  }
}

And that’s it! Understanding constructor functions is one of the more advanced topics of the JavaScript world, but by breaking down each step they can be fully understood.

Context Is Key

« "this" Keyword In-Depth

Functions Calling Themselves

Recursive Functions »