Ionică Bizău
Ionică Bizău

Reputation: 113385

Check if the constructor call is coming from extended class

Suppose we have two libraries:

  1. A library written by someone, using the function and prototype syntax to build class-like types in JS.

  2. A library we write, using ES6, extending the first library.

Using class OurLibrary extends TheOtherLibrary {...} works fine (even TheOtherLibrary is declared using function TheOtherLibrary (...) {...} and its methods are appended using the prototype way).

The problem is that when not using classes, you can return values. A common way is to handle calls without new. That's the problem I'm running into now.

We have something like this:

function TheOtherLibrary (foo) {
  if (this.constructor !== TheOtherLibrary) {
     return new TheOtherLibrary(foo);
  }
  //...
}
TheOtherLibrary.someMethod = function () {/*...*/};

class MyLibrary extends TheOtherLibrary {
   constructor (foo) {
       super(foo);
   }
   anotherMethod () {/*...*/}
}

var bar = new MyLibrary(42);
console.log(bar.constructor.name);
// => TheOtherLibrary
console.log(bar.anotherMethod);
// => undefined

So, how to improve the if expression from the second line to check if the call is coming from an extended class?

var notCalledFromExtendedClass = ???
if (this.constructor !== TheOtherLibrary && !notCalledFromExtendedClass) {
   return new TheOtherLibrary(foo);
}

Or is there a hope to get this working in another better way?

Upvotes: 1

Views: 876

Answers (1)

jfriend00
jfriend00

Reputation: 707546

Use instanceof like this to detect whether TheOtherLibrary is anywhere in the prototype chain:

function TheOtherLibrary (foo) {
  if (!(this instanceof TheOtherLibrary)) {
     return new TheOtherLibrary(foo);
  }
  ...
}

This will work for a direct instance of TheOtherLibrary or for an instance of any derived class. If you want to support calling without new for the derived classes too, then you have to put this structure in the constructor for the derived classes too so you catch whatever constructor function is being called without foo and can then create the right type of object.

Upvotes: 1

Related Questions