How to overload constructors in JavaScript ECMA6?

Flame_Phoenix picture Flame_Phoenix · Jul 7, 2016 · Viewed 16.9k times · Source

Objective

Implement a mechanism to allow constructor overload in JavaScript ECMA6

Why this is not a duplicate

The topic Why doesn't JavaScript ES6 support multi-constructor classes?, although similar is not the same as this one. The other topic merely focuses on a constructor overloading using the old ECMAScript versions, while this topic focuses on ECMA6. If you are looking for an updated answer, this is the place.

Background

I have a JavaScript class with a given constructor, and I want the user to be able to have different constructors when instantiating an object. An example of what I pretend could be the following:

const DEFAULT_WHEEL_NUMBER = 4;
const DEFAULT_COLOR = "black";    
const DEFAULT_NAME = "myCar";

class Car{

    constructor(numberWheels, aName, aColor){
        this.wheelsNum = numberWheels;
        this.name = aName;
        this.color = aColor;
    }

    constructor(aName){
        this(DEFUALT_WHEEL_NUMBER, aName, DEFAULT_COLOR);
    }

    constructor(){
        this(DEFUALT_WHEEL_NUMBER, DEFAULT_NAME, DEFAULT_COLOR);
    }
}

In this code, the user has three constructors he can use, each one taking a different amount of parameters. An usage example follows:

var car1 = new Car(3, "tricicle-car", "white");
var car2 = new Car("Opel"); //creates black car with 4 wheels called Opel
var car3 = new Car(); //creates a black car, with 4 wheels called myCar

Problem

This is a straightforward example if one is using Java or C#, because those languages have constructor overloads.

However, from the documentation on classes from MDN one can conclude that JavaScript does not.

Question

  1. Is there a way to implement a similar mechanism for JavaScript classes using ECMA6? If not, what is the best/closest alternative?

Answer

meskobalazs picture meskobalazs · Jul 7, 2016

There is no in-built solution for this in JavaScript. An alternative solution can be using the arguments object (in some cases), or passing your own configuration options, similar to this:

const defaults = {
    numberWheels: 4,
    color: "black",   
    name: "myCar"
}

class Car {
    constructor(options) {
         this.wheelsNum = options.numberWheels || defaults.numberWheels;
         this.name = options.name || defaults.name;
         this.color = options.color || defaults.color;
    }
}

This is basically the old school solution, I use the same logic in ES3.