В примере выше мы использовалиsuper
для вызова конструктора-родителя. С помощью подобного вызова мы записали свойствоname
для текущего объекта. Другуми словами, всё, что делаетsuper
при вызове внутри конструктора (свойстваconstructor
) — вызывает конструктор родителя и записывает в текущий объект (то есть вthis
) всё, что от него требуется. В ES5 для подобных действий приходилось напрямую обращаться к конструктору:
Онлайн курс по React JS в Виннице
var GreatPerson = function(name, phrase) {
// Пердача всех аргументов в конструктор родителя
Person.apply(this, arguments);
// или только одного
Person.call(this, name);
// запись новых свойств
this.phrase = phrase;
};
Но это ещё не всё, чем может порадоватьsuper
! Если вы захотите обратиться к любому методу, записанному в прототип родителя внутри метода потомка, тоsuper
и здесь вас сможет выручить.
class Person {
constructor(name) {
this.name = name;
}
speak(phrase) {
return `${this.name} says ${phrase}`;
}
}
class Speaker extends Person {
speak(phrase) {
console.log(`${super.speak(phrase)} very confidently`);
}
}
const bob = new Speaker('Bob');
const john = new Person('John');
console.log(john.speak('I don\'t have a lot of money'));
// John says "I don't have a lot of money"
bob.speak('I have a lot of money');
// Bob says "I have a lot of money" very confidently
Безsuper
нам бы пришлось напрямую обращаться к прототипу конструктора родителя, чтобы получить перезаписанный нами метод:
var Person = function(name) {
this.name = name;
};
Person.prototype.speak = function(phrase) {
return `${this.name} says "${phrase}"`;
};
var Speaker = function(name) {
Person.call(this, name);
};
Speaker.prototype = Object.create(Person.prototype);
Speaker.prototype.speak = function(phrase) {
// обращаемся к методу speak из функции родителя
var originalSpeak = Person.prototype.speak;
// в добавок ко всему нужно использовать и call
console.log(originalSpeak.call(this, phrase) + ' very confidently');
};
Таким образом,super
“оценивает ситуацию” и в зависимости от того, где вы его решили использовать будет работать по-разному, но при любом использовании он готов достаточно сильно сократить ваш код и избавить от не самого понятного способа вызова конструктора родителя.
Подводный каменьsuper
: при реализации наследования с помощьюextends
и работе с дочерним конструктором необходимо вызватьsuper()
перед добавлением любого нового свойства.
class Pesron {
constructor(name) {
this.name = name;
}
}
// Всё работает хорошо
class GreatPerson extends Person {
constructor(name, phrase) {
// Необходимо вызвать super
super(name);
this.phrase = phrase;
}
}
// А тут ошибка
class GreatPerson extends Person {
constructor(name, phrase) {
// Необходимо вызвать super до записи собственных свойств
this.phrase = phrase;
super(name);
}
}
Онлайн курс по React JS в Виннице | Frontend, обучение, уроки, ментор - ReactWarriors