How to invoke an arbitrary parent method in a Mootools extended Class

javascript, mootools

Solution

you can still do it as per 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 make this a mixin to call any method from upstream proto only rather than relying on proto chain...

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);
        }
    }
});

via `Implements: [Super]` and then `this.Super('foo', arg1, arg2)`. you can make it `return this[method](args)` if it can't find it on the parent.

this may not scale for multiple extended classes, it has no way of knowing which parent you really mean - resolution flow should be natural.

also, if you extend a class and override a method but still need the original from other methods, perhaps you are doing the wrong thing whilst creating a possible violation of LSP.

I'd refactor to indicate the difference between `my.bar` vs `parent.bar`, eg, `my.barClub` vs `my.bar` or `parent.bar`, has semantic meaning that is clear to understand and maintain. your local methods will know of the existance of `bar` and `barClub` whereas the parent will only care about a "normal" `bar`. you can determine which to call via conditions from within your subclass.

within your local `barClub` you can also do `this.bar()` which will call from the Super.

as is, it may be very hard to follow/understand/debug the behaviour. be kind to your future self :)

have fun

Problem

In Mootools, I can use `this.parent()` to invoke the current executing method in the parent class: ``` foo: function() { this.parent(); // Equals to super.foo() in Java } ``` But what if I want to invoke another parent method that I had overridden in child class? ``` bar: function() { // Overriden bar() method }, foo: function() { ??? // Equals to super.bar() in Java } ```

Original source