Javascript 如何使用与我所在的名称不同的名称调用父方法?
我想从Javascript 如何使用与我所在的名称不同的名称调用父方法?,javascript,inheritance,mootools,Javascript,Inheritance,Mootools,我想从[Child].g()中调用[Parent].f(),而不是[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()
[Child].g()中调用[Parent].f()
,而不是[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()
?通过查看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;
}
您遇到的问题是Child
hasOwnProperty
f
,因此调用Child.f()
将在实例而不是原型上获得它
不要像另一个答案中建议的那样切换this.$caller.$name
,直接从父原型调用它即可:
this.$constructor.parent.prototype.f.call(this);
// or
this.$constructor.parent.prototype.f.apply(this, arguments);
当然,如果您不关心反射,您可以只做p.prototype.f.call(this)
——但它是非干性的,因为它意味着方法需要知道超级用户的名称
这种方法的问题是,如果父级正在扩展另一个父级,那么它是否会起作用,等等,但在大多数情况下,它应该是好的。如果子级没有父级或没有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