Co je to prototypové dědění v JavaScriptu?
sobes.tech AI
Odpověď od AI
V JavaScriptu objekty dědí vlastnosti a metody od svých prototypů. Prototyp každého objektu je jiný objekt, jehož vlastnosti a metody jsou dostupné přes řetězec prototypů.
Při přístupu k vlastnosti objektu JavaScript nejprve hledá přímo v samotném objektu. Pokud vlastnost nenajde, pokračuje v hledání v prototypu tohoto objektu, poté v prototypu prototypu a tak dále, dokud vlastnost nenajde nebo nedosáhne konce řetězce (null).
Prototypové dědění se liší od klasického dědění (například v Java nebo C++), kde jsou objekty vytvářeny z tříd, které popisují jejich strukturu a chování. V JavaScriptu jsou třídy, které se objevily v ES6, syntaktickým cukrem nad prototypovým děděním.
Hlavní aspekty:
- __proto__: Vnitřní vlastnost objektu, odkazující na jeho prototyp.
- prototype: Vlastnost konstruktoru (funkce používané jako konstruktor), odkazující na objekt, který bude sloužit jako prototyp pro vytvářené instance.
- Object.getPrototypeOf(obj): Standardní způsob získání prototypu objektu.
- Object.setPrototypeOf(obj, proto): Standardní způsob nastavení prototypu objektu.
Příklad:
// Konstruktorová funkce
function Animal(name) {
this.name = name;
}
// Přidání metody do prototypu Animal
Animal.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
// Vytvoření instance
const dog = new Animal("Buddy");
// Volání metody z prototypu
dog.sayHello(); // Výstup: Hello, my name is Buddy
// Prototyp psa je Animal.prototype
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // Výstup: true
// Prototyp Animal.prototype je Object.prototype
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // Výstup: true
// Konec řetězce prototypů je null
console.log(Object.getPrototypeOf(Object.prototype) === null); // Výstup: true
Porovnání s klasickým děděním (pomocí tříd ES6):
class Animal {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello, my name is ${this.name}`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Volání konstruktoru rodičovské třídy
this.breed = breed;
}
bark() {
console.log("Woof!");
}
}
const buddy = new Dog("Buddy", "Golden Retriever");
buddy.sayHello(); // Výstup: Hello, my name is Buddy (dědí od Animal)
buddy.bark(); // Výstup: Woof! (metoda Dog)
// Třídy v ES6 jsou cukrem nad prototypy
console.log(Object.getPrototypeOf(Dog) === Animal); // Výstup: true (dědění mezi třídami)
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // Výstup: true (dědění metod přes prototypy)
console.log(Object.getPrototypeOf(buddy) === Dog.prototype); // Výstup: true (instance dědí od prototypu třídy)
Prototypové dědění je klíčovou koncepcí v JavaScriptu, jejíž pochopení je nezbytné pro efektivní práci s tímto jazykem.