简体   繁体   中英

Add an optional parameter to a constructor that already has optional parameters in JavaScript

I'm currently working on a node.js project that supports es6 classes and I need to add an optional parameter to a class constructor that is being called several times, but the problem is that the class constructor already has one optional parameter.

So my question is, is there a way I can add another optional parameter without having to refactor all places where the class is instantiated and still have a clear syntax?

The code I have so far looks like this:

// Error class
class MyError extends Error {
    constructor( message = "default message") {
      super(message)
    }
}

...

// Being called as 
throw new MyError()

And I would like to add another optional parameter:

class MyError extends Error {
    constructor( message = "default message", code = 500) {
      super(message);
      this.code = code;
    }
}

...

// But if I do it like this, then I always have to inform message when I instantiate MyError:
throw new MyError(undefined, 400)

Is there an approach to adding an optional parameter that would allow me to avoid refactoring previous calls and still allow me to omit the undefined when I create a new instance of MyError with a custom code?

I know for example that I could use object destructuring to have named parameters:

class MyError extends Error {
    constructor( { message = "default message", code = 500 } = {} ) {
      super(message);
      this.code = code;
    }
}

...

// But then I would have to refactor all places that call MyError with a message to 
throw new MyError({ message: "OldMessage"})

Given that you have already had to refactor this once, the best approach is going to be doing the work now so that you don't have to in the future.

You should go the route of object destructuring. If you are against refectoring everything now, you can add this as a new constructor and refactor at a later point, but it is highly recommended that you perform all this at once.

As commented by others, it is best to keep with the parameter structure of Error from which this class inherits, and not be disturbed by new MyError(undefined, 400) .

If however you really want to go ahead with the object parameter, then you could make it backwards compatible like this:

class MyError extends Error {
    constructor(options = { message: "default message", code: 500 }) {
        super(typeof options === "string" ? options : options?.message);
        if (typeof options === "string") options = { message: options, code: 500 };
        this.message = options?.message;
        this.code = options?.code;
        // rest of your code
    }
}

This would allow old-style code like new MyError("OldMessage") to continue to work, while newer code can do any of these:

new MyError({ message: "NewMessage" });
new MyError({ code: 404 });
new MyError({ message: "NewMessage", code: 404 });

This gives you time to refactor the code at your convenience.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM