This question already has an answer here:
Parent constructor call overridden functions before all child constructors are finished
(1个答案)
5年前关闭。
我在下面遇到了JavaScript(ES6)问题
我期望的是
但实际上是
我知道我可以通过在B类的foo函数中添加
但是,想象一下类似的情况:
子级必须重写父级的功能,以完成一些额外的工作,并防止外部访问能够访问原始项。
似乎在构建父
如何使
还是在这种情况下有更好的解决方案?
编辑
因此,在阅读答案后,主要问题变为-
不鼓励在 child 的JavaScript中将
为了更清楚地说明情况:(很抱歉,我之前的错误示例:()
这是个坏主意,因为 child 可以覆盖该功能吗?
所以我不应该像Java,C++那样在构造函数中使用
我必须手动调用类似
(1个答案)
5年前关闭。
我在下面遇到了JavaScript(ES6)问题
class A{
constructor(){
this.foo();
}
foo(){
console.log("foo in A is called");
}
}
class B extends A{
constructor(){
super();
this.foo();
}
foo(){
console.log("foo in B is called");
}
}
我期望的是
foo in A is called
foo in B is called
但实际上是
foo in B is called
foo in B is called
我知道我可以通过在B类的foo函数中添加
super.foo()
来解决此问题class B extends A{
constructor(){
super();
this.foo();
}
foo(){
super.foo() // add this line
console.log("foo in B is called");
}
}
但是,想象一下类似的情况:
子级必须重写父级的功能,以完成一些额外的工作,并防止外部访问能够访问原始项。
class B extends A{
constructor(){
super();
this.initBar();
}
foo(){
super.foo();
this.bar.run(); //undefined
console.log("foo in B is called");
}
initBar(){
this.bar.run = function(){
console.log("bar is running");
};
}
}
似乎在构建父
this
时B
仍指向子A
。这就是为什么我无法到达父A
的foo
的原因。如何使
this
调用构造函数链中被子项覆盖的父版本函数?还是在这种情况下有更好的解决方案?
编辑
因此,在阅读答案后,主要问题变为-
不鼓励在 child 的JavaScript中将
initialize helpers
或setter functions
放在JavaScript的构造函数中吗? 为了更清楚地说明情况:(很抱歉,我之前的错误示例:()
class A{
constructor(name){
this.setName(name);
}
setName(name){
this._name = name;
}
}
class B extends A{
constructor(name){
super(name);
this._div = document.createElementById("div");
}
setName(name){
super.setName(name);
this._div.appendChild(document.createTextNode(name));
}
}
new B("foo")
this._div
将是undefined
。这是个坏主意,因为 child 可以覆盖该功能吗?
class A{
constructor(name){
this.setName(name); // Is it bad?
}
...
}
所以我不应该像Java,C++那样在构造函数中使用
initialize helpers
或setter functions
...?我必须手动调用类似
new A().init()
的东西来帮助我初始化吗? 最佳答案
您似乎误以为在派生类A
的构造函数中有两个对象B
和B
。根本不是这种情况。只有一个对象。 A
和B
都为该对象提供属性和方法。在创建B类对象的过程中,this
的值在B
的构造函数中与在A
的构造器中相同。
ES6类语法仅是将ES5方法用于对象类型的原型(prototype),而实际上,原型(prototype)仍在幕后使用。这样,当您像在类B中一样在派生类中定义方法foo
时,它仍在分配给原型(prototype),并且该分配会覆盖来自父定义的原型(prototype)上可能已经存在的任何同名方法。这就是this.foo()
引用foo
的B类版本的原因。如果您想达到A类版本的foo
,那么您将已经手动使用super
进行指定,就像您已经知道的那样。
至于您的具体问题:
子B和父A不是独立的对象。父级A和子级B都引用一个对象。父A和子B的方法或构造函数将看到this
的值完全相同。
您似乎已经知道,可以使用super
直接引用父方法。
super
是解决方案。
仅供引用,这是关于ES6类的很好的讨论,包括super
的工作方式:Classes in ECMAScript 6 (final semantics)。第4.4节似乎与您的问题/理解特别相关。