我花了几个小时试图找到解决问题的办法,但似乎毫无希望。
基本上,我需要知道如何从子类调用父方法。
到目前为止,我所尝试的所有东西都以无效或重写父方法而告终。
我使用下面的代码在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中完成的。
任何帮助都非常感激,谢谢!
虽然您可以通过父方法的原型调用父方法,但您将需要传递当前的子实例以使用调用、应用或绑定方法。bind方法会创建一个新函数,所以如果你关心性能,我不建议你这样做,除非它只被调用一次。
作为一种替代方法,您可以替换子方法,并在调用原始子方法时将父方法放在实例上。
function proxy(context, parent){
var proto = parent.prototype;
var list = Object.getOwnPropertyNames(proto);
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]){
let currentMethod = context[key];
let parentMethod = proto[key];
context[key] = function(){
context.super = parentMethod;
return currentMethod.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 super.add(arg) + ", Child "+arg;
}
}
var family = new Child();
console.log(family.add('B'));
Well in order to do this, you are not limited with the Class abstraction of ES6. Accessing the parent constructor's prototype methods is possible through the __proto__ property (I am pretty sure there will be fellow JS coders to complain that it's depreciated) which is depreciated but at the same time discovered that it is actually an essential tool for sub-classing needs (especially for the Array sub-classing needs though). So while the __proto__ property is still available in all major JS engines that i know, ES6 introduced the Object.getPrototypeOf() functionality on top of it. The super() tool in the Class abstraction is a syntactical sugar of this.
因此,如果你没有访问父构造函数的名称,并且不想使用Class抽象,你仍然可以这样做;
function ChildObject(name) {
// call the parent's constructor
ParentObject.call(this, name);
this.myMethod = function(arg) {
//this.__proto__.__proto__.myMethod.call(this,arg);
Object.getPrototypeOf(Object.getPrototypeOf(this)).myMethod.call(this,arg);
}
}