Sobes.tech
Middle

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.