Я столкнулся с проблемой ниже с 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
Я знаю, что могу решить эту проблему, просто добавив super.foo()
в функцию foo класса B.
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
. Вот почему я не могу связаться с foo
родителя A
.
Как заставить this
вызывать функцию родительской версии, которая переопределяется дочерним элементом во время цепочки конструкторов?
Или есть лучшее решение, когда дело доходит до такого сценария?
Изменить
Итак, после прочтения ответов главный вопрос становится --
Не рекомендуется ли помещать 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
.
Это плохая идея, так как ребенок сможет переопределить функцию?
class A{
constructor(name){
this.setName(name); // Is it bad?
}
...
}
Так что я не должен использовать initialize helpers
или setter functions
в конструкторе, как в Java, C++...?
Должен ли я вручную вызывать подобные вещи new A().init()
, чтобы помочь мне инициализировать вещи?
this
вызывать функцию родительской версии -super
- единственный способ. - person thefourtheye   schedule 16.09.2015A
вообще вызываетthis.foo()
? Он не должен, он должен только инициализировать экземпляр. - person Bergi   schedule 16.09.2015foo
для переопределения родительской реализации в общем случае, или вы больше спрашиваете, как сделать foo некоторым частным помощником? - person loganfsmyth   schedule 16.09.2015foo
в классе B, оно по-прежнему переопределяет определениеfoo
в прототипе, и этоthis.foo()
независимо от того, где вы его вызываете, будет ссылаться на определение класса B. Как вы, кажется, уже знаете, если вы хотите вызвать версию foo класса A, вы должны сделать это вручную. - person jfriend00   schedule 16.09.2015this
не указывает на дочерний элемент B.this
указывает на весь объект, в котором и A, и B имеют свойства экземпляра и методы прототипа. Существует только один объект, в котором свойства и методы вносят вклад как A, так и B. Вот почему есть только одинthis
и почемуthis.foo
указывает на самое последнее переопределение. - person jfriend00   schedule 16.09.2015