32

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?
6
  • 2
    Take a look at this very similar question: Why JavaScript ES6 doesn't have multi-constructor class? Commented Jul 7, 2016 at 8:37
  • 2
    I think the ultimate problem is that Javascript just isn't Java and mimicking Java idioms leads to a lot of trouble in general. That's just my opinion though. Commented Jul 7, 2016 at 8:44
  • A great question if you actually think that overloading is a good idea. Your example screams "Builder". Commented Jul 7, 2016 at 10:19
  • @zeroflagL: perhaps you could be kind enough to provide an answer with an example? I am a fan of patterns ! Commented Jul 7, 2016 at 10:25
  • 1
    Take a look to TypeScript. They use typed objects, like object: int Commented Jul 7, 2016 at 13:48

2 Answers 2

27

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Instead of the arguments object you can use ...restParameters, which gives you a real array.
When using || operator, you should put options parameter first, because otherwise you will always get the default object.
whoops, true :) updated it, thanks
24

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!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.