2

I am creating a class and its subclasses, where I am required to call a static method of the parent to return a child instance.

class Animal{
  static findOne(){
    // this has to return either an instance of Human
    // or an instance of Dog according to what calls it
    // How can I call new Human() or new Dog() here? 
  }
}

class Human extends Animal{
}

class Dog extends Animal{
}

const human = Human.findOne() //returns a Human instance
const day = Dog.findOne() //returns a Dog instance
Kucl Stha
  • 565
  • 1
  • 6
  • 20
  • 4
    `return new this;` – Keith Jun 21 '18 at 09:15
  • @destoryer the findOne in the animal class should not know what calls it. – Kucl Stha Jun 21 '18 at 09:19
  • 1
    @Keith that does not work, it returns `this is not a constructor` error – Kucl Stha Jun 21 '18 at 09:20
  • 1
    @InfiniteDev Does it? Works for me… – deceze Jun 21 '18 at 09:23
  • 1
    Works for me in `Edge` / `Chrome` / `Firefox`, what browser you using? Just a though, the error your seeing, is not a Linting error is it? – Keith Jun 21 '18 at 09:24
  • @Keith I am using it in backend node – Kucl Stha Jun 21 '18 at 09:25
  • 2
    Works in node too, what version of node you using.? And is kind of expected as it's based on Chromes JS V8 engine. – Keith Jun 21 '18 at 09:27
  • @Keith thank you it works. I had a the rules nested inside the function() i changed it to arrow function and it works perfectly. – Kucl Stha Jun 21 '18 at 09:30
  • LOL, not a problem. Had me well confused!!, testing with the actual script shown in the future might not be a bad idea, just in case of side effects. ps. The reason why this works is due to how JS handles dot notation on objects and is actually nothing special,.. Basically `anything.something()`, `anything` is then set as `this` for `something` when called, seen as `anything` was the actual class, `this` got set to the class. Hope that makes sense. :) – Keith Jun 21 '18 at 09:55

1 Answers1

8

The static method is called with its this value being the class object, the constructor of the subclass that you called it upon. So you can just instantiate that with new:

class Animal {
  static findOne() {
    return new this;
  }
}

class Human extends Animal{
}

class Dog extends Animal{
}

const human = Human.findOne() // returns a Human instance
const dog = Dog.findOne() // returns a Dog instance
Bergi
  • 630,263
  • 148
  • 957
  • 1,375