31

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?
Community
  • 1
  • 1
Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266

2 Answers2

25

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.

meskobalazs
  • 15,741
  • 2
  • 40
  • 63
22

You're right (as far as I know) that this isn't a feature JavaScript classes support. My recommendation here, since you're already making use of ES6 features, would be to make use of default parameters instead:

class Car {
    constructor(numberWheels = 4, aName = "myCar", aColor = "black"){
        this.wheelsNum = numberWheels;
        this.name = aName;
        this.color = aColor;
    }
}

This obviously comes with the caveat that you can't have 'overloads' with different parameter orders like you do in your example (although in my opinion, that's a good thing - a consistent API is much nicer to work with).

meskobalazs's answer is also a good option, especially if you have a lot of options that you want your object to take in. Doing that through function params like this can get a bit messy!

Joe Clay
  • 33,401
  • 4
  • 85
  • 85