Reputation: 113385
Suppose we have two libraries:
A library written by someone, using the function
and prototype
syntax to build class-like types in JS.
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
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