![](/img/trans.png)
[英]JavaScript: How to get child Class's methods in parent's constructor?
[英]Javascript: How to run constructor logic of parent class after overriding inherited methods in child class?
与面向类的语言相反,JS是基于原型的,对象的构造函数不仅包含“构造逻辑”(我在MDN上找到了这个术语),而且构造函数还定义了特权方法。 如果一个“类”是另一类的子类(对不起,我不知道比JS的“类”更好的术语),这将导致以下问题:要么在子类能够覆盖之前执行父构造函数方法或子类无法覆盖方法,因为构造函数尚未运行。
我将举一个例子来说明我的意思。 假设一个“父类”在对象上定义了一个特权函数,并调用了此方法的构造函数逻辑。
function Parent() {
this.methodA = function() {
// do something
};
// C'tor logic starts here
// Beside other things also call some method of this object
this.methodA();
}
假定一个子类应重新定义methodA
但仍使用父类的构造函数逻辑。
第一种方法是在子构造函数的开头调用父构造函数。 但是,父级构造函数仍然会调用父级的实现。
Child.prototype = Object.create( Parent.prototype );
Child.prototype.constructor = Child;
function Child() {
// Call parent constructor first. Problem: The parent constructor
// calls methodA before it will be overriden by child constructor
Parent.call( this );
var _oldMethodA = this.methodA;
this.methodA = function() {
// do something special and then call parent method
_oldMethodA.call( this );
};
}
第二种方法是稍后调用父构造函数,但是,不能重写父方法。
Child.prototype = Object.create( Parent.prototype );
Child.prototype.constructor = Child;
function Child() {
// Override first. Problem: The parent constructor has not defined methodA
// yet, hence the line below fails.
var _oldMethodA = this.methodA;
this.methodA = function() {
// do something special and call parent method
_oldMethodA.call( this );
};
Parent.call( this );
}
如何交错JS构造函数的两个任务-特权方法的定义和构造函数逻辑-以正确的顺序调用?
附录-需要评论的其他材料
我从评论中发现,似乎不清楚我想要什么。 所以这是用Java编写的示例
class Parent {
public Parent() {
methodA();
}
public void methodA() {
System.out.println( "I do the work of the parent's method" );
}
}
class Child extends Parent {
public Child {
super();
}
public void methodA() {
System.out.println( "I do the work of the child's method and ..." );
super();
}
}
Parent p = new Parent();
Child c = new Child();
结果为以下输出
$> I do the work of the parent's method
$> I do the work of the child's method and ...
$> I do the work of the parent's method
这就是发生的情况。 的构造Parent
呼吁实行methodA
中定义Parent
。 这没什么特别的,它会产生第一行输出。 Child
的构造函数只调用父级的构造函数,该构造函数再次像以前一样调用methodA
。 但是,尽管这是父级的构造方法,但是该对象仍然是Child
的实例,因此将执行child类的methodA
的实现。 此方法输出第二行输出,然后显式调用生成第三行的父级方法。
根据OOP,这是完美的正确行为,这也是我也希望使用Javascript实现的行为。 因此,实际上与这里提到的问题相反 。 链接来自评论。
您可以在调用父类之前将该属性定义为子类中的访问器。
这样,您将能够获得对父类分配的函数的引用,但仍可以在getter中提供所需的函数。
function Parent() { this.methodA = function() { console.log('Parent method'); }; this.methodA(); } function Child() { var _oldMethodA; var _newMethodA = function() { console.log('Code injected by Child'); _oldMethodA.call( this ); }; Object.defineProperty(this, 'methodA', { configurable: true, enumerable: true, set: function(val){ _oldMethodA = val; }, get: function(){ return _newMethodA; } }); Parent.call(this); /* Optional: convert it back to a data property */ Object.defineProperty(this, 'methodA', { value: _newMethodA, writable: true }); } Child.prototype = Object.create( Parent.prototype ); Child.prototype.constructor = Child; new Child();
不确定您要在这里实现什么,但是一般来说您可以执行以下操作:
function Parent() {
if (this.methodA == null) {
this.methodA = function() {
// do something
console.log('parent');
};
}
// C'tor logic starts here
// Beside other things also call some method of this object
this.methodA();
}
function Child() {
this.methodA = (function(_oldMethodA) {
return function() {
console.log('child');
// do something special and then call parent method
if (_oldMethodA) {
_oldMethodA.call( this );
}
}
})(this.methodA);
Parent.call( this );
}
Child.prototype = Object.create( Parent.prototype );
Child.prototype.constructor = Child;
new Child(); // yields: 'child'
但是判断您要执行的操作时,可能要在父级中添加一些数组,这是您在父类中覆盖methodA
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.