extends
Tworzy klasę pochodną, która dziedziczy metody innej klasy i może je rozszerzać lub nadpisywać.
Przykład
#class Exercise {
constructor(title, points) {
this.title = title
this.points = points
}
describe() {
return `${this.title} (${this.points} pkt)`
}
}
class Quiz extends Exercise {
constructor(title, points, questions) {
super(title, points)
this.questions = questions
}
}
const quiz = new Quiz('Test z pętli', 10, 5)
console.log(quiz.describe())
console.log(quiz)
console.log(quiz instanceof Exercise)Definicja i zastosowanie
#Słowo extends w deklaracji klasy wskazuje klasę bazową, czyli rodzica. Klasa pochodna dostaje wszystkie jego metody i może dodać własne albo nadpisać odziedziczone, zapisując metodę o tej samej nazwie. Pod spodem działa łańcuch prototypów: prototyp klasy pochodnej wskazuje na prototyp klasy bazowej.
Jeśli klasa pochodna ma własny konstruktor, musi w nim wywołać super(...), zanim pierwszy raz użyje this. To konstruktor rodzica tworzy obiekt, a dopiero potem klasa pochodna może dopisać swoje pola. Gdy klasa pochodna nie ma konstruktora, JavaScript doda domyślny, który przekaże wszystkie argumenty do rodzica.
Po extends może stać dowolne wyrażenie zwracające konstruktor, także klasa wbudowana, jak Error, Array czy Map. Dziedziczyć można tylko po jednej klasie. Gdy chcesz połączyć zachowania z kilku źródeł, zwykle lepsza jest kompozycja, czyli trzymanie innych obiektów w polach.
Składnia
#class Child extends Parent {
constructor(...args) {
super(...args)
}
}
class MyError extends Error {}Parametry
#Parent
klasa
Klasa bazowa, po której dziedziczy nowa klasa. Może to być też klasa wbudowana, np.ErrorlubArray.
Więcej przykładów
#class Exercise {
constructor(title) {
this.title = title
}
reward() {
return 5
}
}
class Project extends Exercise {
reward() {
return 25
}
}
const tasks = [new Exercise('Pytanie ABCD'), new Project('Strona wizytówka')]
for (const task of tasks) {
console.log(task.title, task.reward())
}Klasa Project nie ma konstruktora, więc JavaScript użył domyślnego, który przekazał tytuł do konstruktora Exercise.
class Student {
constructor(name) {
this.name = name
}
}
class Mentor extends Student {
constructor(name, course) {
this.course = course
super(name)
}
}
try {
new Mentor('Kuba', 'React')
} catch (error) {
console.log(error.name)
}Obiekt powstaje dopiero w konstruktorze rodzica, więc przed wywołaniem super() nie ma jeszcze czego przypisać do this. Treść komunikatu błędu różni się między przeglądarkami.
class Playlist extends Array {
totalMinutes() {
return this.reduce((sum, video) => sum + video.minutes, 0)
}
}
const playlist = new Playlist()
playlist.push({ title: 'Wstęp', minutes: 4 }, { title: 'Pętle', minutes: 11 })
console.log(playlist.length)
console.log(playlist.totalMinutes())
console.log(Array.isArray(playlist))Obsługa przeglądarek
#Szeroko dostępne
Działa we wszystkich nowoczesnych przeglądarkach, także na telefonach. Możesz używać bez obaw.
- Chrome
- Edge
- Firefox
- Safari
Dobre praktyki
#- Dziedzicz tylko wtedy, gdy klasa pochodna naprawdę jest odmianą klasy bazowej, np. quiz jest zadaniem. Gdy obiekt tylko ma inny obiekt, np. gracz ma ekwipunek, wybierz kompozycję.
- W konstruktorze klasy pochodnej wywołuj
super()na samym początku. Użyciethisprzed nim kończy się błędemReferenceError. - Unikaj głębokich hierarchii. Dwa, trzy poziomy dziedziczenia to zwykle rozsądne maksimum, dalej kod trudno śledzić.
Powiązane hasła
#- classDefiniuje klasę, czyli szablon do tworzenia obiektów z tymi samymi polami i metodami.
- superOdwołuje się do klasy bazowej: wywołuje jej konstruktor albo jej wersję metody.
- instanceofSprawdza, czy obiekt został utworzony przez daną klasę albo przez klasę, która po niej dziedziczy.
- staticOznacza pole lub metodę należącą do samej klasy, a nie do obiektów tworzonych przez new.
- #polePola i metody z prefiksem # są prywatne: dostęp do nich ma wyłącznie kod wewnątrz klasy.
Widzisz błąd albo brakuje przykładu? Napisz do nas.