2

ではなく[Parent].f()中から呼び出したい。[Child].g()[Child].f()

MooTools コードがあるとします。

var Parent = new Class({
    f: function () {
        console.log('Parent.f()');
    }
});

var Child = new Class({
    Extends: Parent,

    f: function () {
        console.log('Child.f()');
    },

    g: function () {
        // Call Parent.f()
        this.parent.f();
    }
});

var o = new Child();

o.g();

this.parent.f()MooTools はthis.parent、現在のメソッドと同じ名前の親クラスのメソッドを作成するため、明らかにナンセンスです。つまり、Child.g()これは になりますParent.g()

では、どうすれば電話できますP.f()か?

4

2 に答える 2

3

あなたが抱えている問題はChild hasOwnProperty f、そのため、呼び出すchild.f()と、プロトタイプではなくインスタンスで取得されます。

別の回答で提案されているように切り替えてハックするのではなくthis.$caller.$name、親プロトタイプから直接呼び出すだけです。

this.$constructor.parent.prototype.f.call(this);
// or
this.$constructor.parent.prototype.f.apply(this, arguments);

もちろん、Reflection っぽいことを気にしないのであれば、そのままでもかまいませんがP.prototype.f.call(this)、メソッドがスーパーの名前を知る必要があることを意味するため、DRY ではありません。

このアプローチの問題は、親が別の親を拡張している場合などに機能するかどうかですが、ほとんどの場合は問題ありません。Child が親または no を持たない場合にも失敗します。fその場合、論理的に の独自の実装を実行するように戻す必要がありfます。

var Parent = new Class({
    f: function(msg){
        console.log('Parent.f() says ' + msg);
    }
});

var Child = new Class({
    Extends: Parent,
    f: function(){
        console.log('Child.f()');
    },   
    g: function(){
        // Call Parent.f()
        this.$constructor.parent.prototype.f.apply(this, arguments);
    }
});

new Child().g('hello');

これを頻繁に行う必要がある場合は、親クラスに mixin として新しいメソッドを作成できます。例えば。

Class.parenting = new Class({
    // mixin class that allows call
    _parent: function(method, args){
        this.$constructor.parent.prototype[method].apply(this, args);    
    }.protect() // private, restricted to methods
});

var Parent = new Class({
    Implements: [Class.parenting],
    f: function(msg){
        console.log('Parent.f() says ' + msg);
    }
});

var Child = new Class({
    Extends: Parent,
    f: function(){
        console.log('Child.f()');
    },   
    g: function(){
        this._parent('f', arguments);
    }
});

var c = new Child();
c.g('hello');
c._parent('f'); // throws, only instances methods can call this
于 2013-11-15T10:46:03.227 に答える
0

MooTools のコードを調べると、これを行うかなり手っ取り早い厄介な方法がありますが、新しいバージョンの MooTools では機能しない可能性があります。

this.$caller.$name呼び出したいメソッドに設定し、呼び出し後にリセットすることで機能します。

    g: function () {
         var oldName = this.$caller.$name;
         this.$caller.$name = 'f';

         try {
             this.parent(...);
         } catch (e) {
             this.$caller.$name = oldName; // Ensure name is always reset
             throw e;
         }

         this.$caller.$name = oldName;
     }
于 2013-11-15T09:46:33.247 に答える