How to call an arbitrary parent method in a Mootools extended class
In Mootools, I can use this.parent()
to call the current run method in the parent class:
foo: function() {
this.parent(); // Equals to super.foo() in Java
}
But what if I want to call a different parent method that has been overridden in the child class?
bar: function() {
// Overriden bar() method
},
foo: function() {
??? // Equals to super.bar() in Java
}
source to share
you can still do it according to javascript
aka.
Super.prototype.foo.apply(this, args);
So in a small example
var Foo = new Class({
name: 'Foo',
foo: function(){
console.log(this.name, '=>foo');
},
baz: function(){
console.log('baz');
}
});
var Bar = new Class({
Extends: Foo,
name: 'Bar',
foo: function(){
console.log(this.name, '=>foo own');
this.parent();
},
bar: function(){
console.log(this.name, '=>bar');
// less DRY and knowledge, apply to my instance
this.$constructor.parent.prototype.foo.call(this);
// without applying to my instance... as static:
this.$constructor.parent.prototype.foo();
Foo.prototype.foo.apply(this); // normal JS way
}
});
var b = new Bar();
b.bar();
Not very nice. Unfortunately it sucks. you can do this mixin to call any method from prototype only upwards and not rely on proto-chaining ...
http://jsfiddle.net/dimitar/oraa1mgb/1/
var Super = new Class({
Super: function(method){
var superMethod = this.$constructor.parent.prototype[method],
args = Array.prototype.slice.call(arguments, 1);
if (!superMethod){
console.log('No ' + method + ' found or no parent proto');
return this;
}
else {
return superMethod.apply(this, args);
}
}
});
through Implements: [Super]
and then this.Super('foo', arg1, arg2)
. you can do it return this[method](args)
if he cannot find it from the parent.
it may not scale to multiple extended classes, it has no way of knowing which parent you really mean - the flow of resolution should be natural.
also, if you extend a class and override a method, but still need the original from other methods, you may be doing the wrong thing, creating a possible LSP violation.
I would refactor to indicate the difference between my.bar
vs parent.bar
, for example my.barClub
vs my.bar
or parent.bar
, has a semantic meaning that is understandable and maintainable. your local methods will be aware of the existence bar
and barClub
, whereas the parent will only care about "normal" bar
. you can define which calls you can fulfill conditions from your subclass.
inside local barClub
you can also do this.bar()
which is called from Super.
as it is, it can be very difficult to follow / understand / debug behavior. be kind to your future self :)
enjoy
source to share