The constructor of a derived class returns an instance of the base class.
The following code explains my problem:
// Vector is defined by an external module (Unreal.js)
class TestB extends Vector {
constructor() {
super();
}
Log() {
console.log("" + this);
}
}
console.log(new TestB() instanceof TestB) // returns false !!! why ???
console.log(new TestB() instanceof Vector) // returns true...
class TestA extends Array {
constructor() {
super();
}
Log() {
console.log("" + this);
}
}
console.log(new TestA() instanceof TestA); // returns true, all is good
How is this possible?
It would appear that Vector
is implemented in a way that makes it incompatible with class
.
Here's an example of one way Vector
could do that:
function Vector() {
var v = Object.create(Vector.prototype);
return v;
}
class TestB extends Vector {
constructor() {
super();
}
}
console.log(new TestB() instanceof TestB); // false
console.log(new TestB() instanceof Vector); // true
The key here is that since Vector
returns a different object than the one new
created, it's of the wrong type. A relatively little-known thing about constructor functions is that if they return a non-null
object reference, the result of new Constructor
is the object the constructor returned, rather than the object new
created.
Here's a snippet for those whose browsers support class
:
function Vector() {
var v = Object.create(Vector.prototype);
return v;
}
class TestB extends Vector {
constructor() {
super();
}
}
console.log(new TestB() instanceof TestB); // false
console.log(new TestB() instanceof Vector); // true
...and a live copy on Babel's REPL for those whose browsers don't.
To my surprise, both Babel and Chrome let me do this using class Vector
as well and returning a value from constructor
; I haven't figured out (yet) from the specification whether it's actually valid:
class Vector {
constructor() {
var v = Object.create(Vector.prototype);
return v;
}
}
class TestB extends Vector {
constructor() {
super();
}
}
console.log(new TestB() instanceof TestB); // false
console.log(new TestB() instanceof Vector); // true
To get around it, you'll likely need to use a per-instance hack, like copying all of TestB.prototype
's methods onto the instance. Ideally, rather than hacking, try to use Vector
via aggregation (aka "composition", e.g., by having a Vector
instance as a property of your class's instances) rather than inheritance, since it's not set up for inheritance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With