2

Based on the JavaScript specification, a class constructor returns the value of this when it gets called by the new keyword.

Can we change the return value to something else? If yes, is it a bad practice? I'm asking if it is a bad practice, for instance, it could be because of some stuff related to the inheritance. For example

class Car {
  constructor(color) {
    this.color = color
    return this.printColor
  }
  printColor = () => {
    console.log(this.color)
  }
}

const car1 = new Car('red')
car1()

Is it a new idea, or is it something normal and the people normally do everyday?

Normal
  • 1,616
  • 15
  • 39
  • 2
    As you can see, you can, I wouldn't say it's *never* used, but it's really weird and I wouldn't do it because it's confusing – CertainPerformance Jul 24 '22 at 06:05
  • 2
    contructor gives birth a child (object), so returning that is a design choice. And now if you have the choice to destroy it, so say you are returning the organs of a full child.. Does that makes sense think this way..? – Arup Rakshit Jul 24 '22 at 06:12
  • @ArupRakshit, omg no that's really sad. I'll stop using this design now right away. now I'm convinced, thank you for the answers. – Normal Jul 24 '22 at 06:14
  • Did you ask this because you want to control the methods/properties in the returned object instead of exposing everything? – Brother58697 Jul 24 '22 at 06:30
  • 1
    You can't return anything from the class constructor, typescript will yell at you. The default return type of constructor is className itself which TypeScript infers meaning that when you do `new ClassName()` it will help you to create instances of the same class, The sole purpose of the constructor is to initialize the instance's properties and create an instance of a class. – Anurag Tripathi Jul 24 '22 at 07:06
  • As I said the default return type of constructor is className itself, taking this fact into account I once return `new className()` from the constructor and it leads to an error "Maximum call stack size exceeded" because by doing so I'm creating an infinite instance of that class(LOL) – Anurag Tripathi Jul 24 '22 at 07:07
  • @Brother58697, no, just because I was writing an npm package, and I thought of this syntax to be used by the client, so instead of him writing `const x = new Car("red").method; x()`, he can directly write `const x = new Car("red"); x()`. because the only method or property my class provides is the `method` method. – Normal Jul 24 '22 at 07:55
  • @Normal You can use a function that returns another function like [this](https://jsbin.com/kuqotow/edit?js,console). Like in the second example, you can put more complex implementation inside. – Brother58697 Jul 24 '22 at 08:14
  • @Brother58697, I don't have an error, my code is fully working, I'm just asking to know the _why_, and the _opinions_. not to end up in a solution. – Normal Jul 24 '22 at 08:44
  • @AnuragTripathi Nobody was asking about TypeScript afaict. But even there, you can `return` a *different* instance than `this` and still have the correct return type. – Bergi Jul 24 '22 at 12:44

1 Answers1

1

A class constructor returns the value of this when it gets called by the new keyword.

See What is the 'new' keyword in JavaScript? and How does the new operator work in JavaScript? for details.

Can we change the return value to something else?

Yes, as long as it is an object, you can override the default by using return - as you did in your example code. See What values can a constructor return to avoid returning this? and What is returned from a constructor? for how that works exactly.

If yes, is it a bad practice?

Yes. Having new Car return a function and not a Car instance is weird and unexpected. People do not do this every day, and they shouldn't start doing it :-)

The only exception is the singleton pattern (which of course is problematic itself), where the constructor may return the singleton instance instead of a new one. (There are however other ways to write JS code for creating singletons, which avoid constructors altogether.)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375