我花了最后几个小时试图找到解决我的问题的方法,但这似乎毫无希望。
基本上,我需要知道如何从子类中调用父方法。到目前为止,我尝试过的所有工作都以无法工作或覆盖父方法而告终。
我正在使用以下代码在javascript中设置OOP:
// SET UP OOP
// surrogate constructor (empty function)
function surrogateCtor() {}
function extend(base, sub) {
// copy the prototype from the base to setup inheritance
surrogateCtor.prototype = base.prototype;
sub.prototype = new surrogateCtor();
sub.prototype.constructor = sub;
}
// parent class
function ParentObject(name) {
this.name = name;
}
// parent's methods
ParentObject.prototype = {
myMethod: function(arg) {
this.name = arg;
}
}
// child
function ChildObject(name) {
// call the parent's constructor
ParentObject.call(this, name);
this.myMethod = function(arg) {
// HOW DO I CALL THE PARENT METHOD HERE?
// do stuff
}
}
// setup the prototype chain
extend(ParentObject, ChildObject);
我需要先调用父方法,然后在子类中向它添加更多内容。
在大多数OOP语言中,就像调用parent.myMethod()
一样简单但我真的无法掌握它在javascript中的完成方式。
非常感谢您的帮助,谢谢!
我花了最后几个小时试图找到解决我的问题的方法,但这似乎毫无希望。基本上,我需要知道如何从子类中调用父方法。我所有的东西...
这是如何完成的:ParentClass.prototype.myMethod();
ES6样式允许您使用新功能,例如super
关键字。当您使用ES6类语法时,super
关键字全部与父类上下文有关。作为一个非常简单的示例,签出:
在多重继承级别的情况下,此函数可以用作其他语言的super()方法。 Here is a demo fiddle,通过一些测试,您可以像这样使用它,在方法内部使用:call_base(this, 'method_name', arguments);
为了执行此操作,您不受限于ES6的Class
抽象。可以通过__proto__
属性访问父构造函数的原型方法(我很确定会有JS编码员抱怨它已贬值),该属性已贬值,但同时发现它实际上是实现以下目的的必要工具:分类需求(尤其是Array子分类需求)。因此,尽管__proto__
属性在我所知道的所有主要JS引擎中仍然可用,但ES6在其之上引入了Object.getPrototypeOf()
功能。 Object.getPrototypeOf()
抽象中的super()
工具是这种语法的语法糖。
基于道格拉斯·克罗克福德思想的东西怎么样:
这是子对象使用JavaScript的原型链访问父级属性和方法的好方法,并且与Internet Explorer兼容。 JavaScript在原型链中搜索方法,我们希望孩子的原型链看起来像这样:
虽然您可以通过父级的原型调用父级方法,但是您需要传递当前的子级实例以使用//Parent constructor
function ParentConstructor(firstName){
//add parent properties:
this.parentProperty = firstName;
}
//add 2 Parent methods:
ParentConstructor.prototype.parentMethod = function(argument){
console.log(
"Parent says: argument=" + argument +
", parentProperty=" + this.parentProperty +
", childProperty=" + this.childProperty
);
};
ParentConstructor.prototype.commonMethod = function(argument){
console.log("Hello from Parent! argument=" + argument);
};
//Child constructor
function ChildConstructor(firstName, lastName){
//first add parent's properties
ParentConstructor.call(this, firstName);
//now add child's properties:
this.childProperty = lastName;
}
//insert Parent's methods into Child's prototype chain
var rCopyParentProto = Object.create(ParentConstructor.prototype);
rCopyParentProto.constructor = ChildConstructor;
ChildConstructor.prototype = rCopyParentProto;
//add 2 Child methods:
ChildConstructor.prototype.childMethod = function(argument){
console.log(
"Child says: argument=" + argument +
", parentProperty=" + this.parentProperty +
", childProperty=" + this.childProperty
);
};
ChildConstructor.prototype.commonMethod = function(argument){
console.log("Hello from Child! argument=" + argument);
// *** call Parent's version of common method
ParentConstructor.prototype.commonMethod(argument);
};
//create an instance of Child
var child_1 = new ChildConstructor('Albert', 'Einstein');
//call Child method
child_1.childMethod('do child method');
//call Parent method
child_1.parentMethod('do parent method');
//call common method
child_1.commonMethod('do common method');
,call
或apply
方法。 bind
方法将创建一个新函数,因此我不建议您在只考虑一次调用的情况下关注性能。
对于多层原型查找,有一种更简单,更紧凑的解决方案,但它需要function proxy(context, parent){
var proto = parent.prototype;
var list = Object.getOwnPropertyNames(proto);
var child = {};
for(var i=0; i<list.length; i++){
var key = list[i];
// Create only when child have similar method name
if(context[key] !== proto[key]){
child[key] = context[key];
context[key] = function(){
context.super = proto[key];
return child[key].apply(context, arguments);
}
}
}
}
// ========= The usage would be like this ==========
class Parent {
first = "Home";
constructor(){
console.log('Parent created');
}
add(arg){
return this.first + ", Parent "+arg;
}
}
class Child extends Parent{
constructor(b){
super();
proxy(this, Parent);
console.log('Child created');
}
// Comment this to call method from parent only
add(arg){
return this.super(arg) + ", Child "+arg;
}
}
var family = new Child();
console.log(family.add('B'));
支持。用法:Proxy
,例如,假设使用方法SUPER(<instance>).<method>(<args>)
的两个类A
和B extends A
:m
。