Reputation: 5233
I'm trying to add extra methods to class, and these extra methods should use the super
methods.
If I add them in the model definition, it works.
class A {
doSomething() {
console.log('logSomething');
}
}
class B extends A {
doSomething() {
super.doSomething();
console.log('logSomethingElse');
}
}
If I try to add the extra method to B.prototype
, I'll get SyntaxError: 'super' keyword unexpected here
.
class A {
doSomething() {
console.log('logSomething');
}
}
class B extends A {
}
B.prototype.doSomething = function doSomething() {
super.doSomething();
console.log('logSomethingElse');
}
It is quite clear, why I get this error. This is a function and not a class method.
Let's try to define the method as a class method, and copy it to the original B
class:
class A {
doSomething() {
console.log('logSomething');
}
}
class B extends A {}
class X {
doSomething() {
super.doSomething();
console.log('2 logSomethingElse');
}
}
B.prototype.doSomething = X.prototype.doSomething;
In this case I'll get TypeError: (intermediate value).doSomething is not a function
.
Is there any way to define methods (that refer to super
) outside from the original class definition, and add these methods later to the original class?
Upvotes: 5
Views: 2255
Reputation: 222369
super
refers to ancestor of a class where the method was defined, it isn't dynamic. As Babel output illustrates this, super
is hard-coded to Object.getPrototypeOf(X.prototype)
, and thus orphan class like this one doesn't make sense because it doesn't have super
:
class X {
doSomething() {
super.doSomething();
...
}
}
But super
can be substituted with dynamic counterpart:
doSomething() {
const dynamicSuper = Object.getPrototypeOf(this.constructor.prototype);
// or
// const dynamicSuper = Object.getPrototypeOf(Object.getPrototypeOf(this));
dynamicSuper.doSomething();
...
}
class B extends A {}
B.prototype.doSomething = doSomething;
In this case it will refer to ancestor class of class instance where doSomething
was assigned as prototype method.
Upvotes: 9
Reputation: 14169
While I think this could be assumed as anti-pattern, you shouldn't use super
outside from a class
.
You can achieve that using Object Literals
.
Refer to Object.setPrototypeOf
const A = {
sayHello() {
console.log("I am A");
},
Factory() {
return Object.create(this);
}
}
const B = {
sayHello() {
super.sayHello();
}
}
Object.setPrototypeOf(B, A);
const c = B.Factory();
c.sayHello();
Upvotes: 1
Reputation: 1179
If you don't make class X inherit from class B or A, the only way to call the method is A.prototype.doSomething()
or more generally A.prototype.doSomething.call(this_substitute, ...args)
.
Upvotes: -2