#javascript #class #oop #inheritance #super
Вопрос:
У меня есть следующие два класса в javascript: Animals
amp; Cat
( Cat
расширяется Animal
). Оба класса будут иметь introduce()
метод; однако Cat
классу требуется некоторая дополнительная информация в этом методе. Поскольку я не хочу дублировать весь метод, я подумал о трех способах достижения этой цели.
Я описал три подхода в комментариях под методом introduct() в классе Cat.
- Первая версия не работает. Для меня это имеет смысл, потому что в нем используется неправильный контекст.
- Вторая версия действительно работает. Это также имеет смысл для меня, потому что я использую
call()
для явного задания контекста. - Третья версия действительно работает. Для меня это не имеет смысла. Чем это отличается от первой версии? Изменяет ли
super
ключевое слово каким-то образом контекст?
Любая помощь будет признательна — спасибо!
class Animal {
constructor(name, age, legs, species, status) {
this.name = name;
this.age = age;
this.legs = legs;
this.species = species;
this.status = status;
}
introduce() {
return `Hello, my name is ${this.name} and I am ${this.age} years old and ${this.status}.`;
}
}
class Cat extends Animal {
constructor(name, age, status) {
super(name, age, 4, 'cat', status);
}
introduce() {
// return Animal.prototype.introduce() ' Meow meow!';
// return Animal.prototype.introduce.call(this) ' Meow meow!';
// return super.introduce() ' Meow meow!';
}
}
Комментарии:
1. » Чем это отличается от первой версии? «потому
super
что ключевое слово создано именно для такого сценария? На самом деле не имело бы смысла иметь его, если бы он на самом деле не работал ни для чего сложного.2. @CRice Ну,
super
используется в других языках ООП для взаимодействия с родительским определением класса. Поэтому, если у вас естьsomeMethod(one) { super.someMerhod(one, "two"); }
, вы бы вызвали родительскую версию метода. В этом примере кода необходимо обеспечить переопределение одного параметра, когда родитель принимает два параметра. Таким образом, в JS осталась та же семантика ООП, поэтому она не слишком отличается от традиционной ООП. В конце концов,class
был введен для имитации традиционного ООП ближе. Так что,super.someMethod()
это своего рода занятиеthis.__proto__.__proto__.someMethid.call(this)
.
Ответ №1:
Третий подход является стандартным способом достижения этой цели. Функционально он такой же, как и 2-я версия. При вызовах формы super[method]()
в качестве контекста задается текущий объект ( this
).
См. Документы MDN.