Срещнах проблем по-долу с 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, трябва да направите това ръчно. - person jfriend00   schedule 16.09.2015this
не сочи към дете B.this
сочи към целия обект, от който и A, и B имат свойства на екземпляра и методи на прототипа. Има само един обект с A и B допринасящи свойства и методи. Ето защо също има само едноthis
и защоthis.foo
сочи към най-скорошната отмяна. - person jfriend00   schedule 16.09.2015