あなたが抱えている問題は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