Sobes.tech
Junior

Vysvetlite, ako funguje dedičstvo v JavaScript.

sobes.tech AI

Odpoveď od AI

Dedičnosť v JavaScripte sa realizuje cez prototypy. Každý objekt v JavaScripte má vnútornú vlastnosť [[Prototype]], ktorá odkazuje na iný objekt. Keď sa pokúšame získať prístup k vlastnosti alebo metóde objektu, ktorý nemá priamo u seba, JavaScript engine hľadá túto vlastnosť alebo metódu v prototypu tohto objektu. Ak ju nenájde, pokračuje v hľadaní po reťazci prototypov, ktorý sa tvorí spojeniami [[Prototype]], až kým nedosiahne null (koniec reťazca).

Existujú dva hlavné mechanizmy dedičnosti:

  1. Klasické prototypové dedičstvo (ES5 a skôr): Je založené na použití konštruktorových funkcií a ich vlastnosti prototype.

    // Konštrukčná funkcia
    function Zviera(meno) {
      this.meno = meno;
    }
    
    // Pridanie metódy do prototypu
    Zviera.prototype.hovorí = function() {
      console.log(`${this.meno} vydáva zvuk.`);
    };
    
    // Vytvorenie inštancie
    const pes = new Zviera('Pes');
    
    // Volanie metódy z prototypu
    pes.hovorí(); // Výstup: Pes vydáva zvuk.
    
    // Prototyp `dog` je `Zviera.prototype`
    console.log(Object.getPrototypeOf(pes) === Zviera.prototype); // true
    
  2. Trieda (ES6 a novšie): Používa syntax class a extends, ktorá pod kapotou stále pracuje s prototypmi.

    // Základná trieda
    class Zviera {
      constructor(meno) {
        this.meno = meno;
      }
    
      hovorí() {
        console.log(`${this.meno} vydáva zvuk.`);
      }
    }
    
    // Podtrieda, ktorá dedí od Zviera
    class Pes extends Zviera {
      constructor(meno, plemená) {
        super(meno); // Volanie konštruktora rodičovskej triedy
        this.plemená = plemená;
      }
    
      štekanie() {
        console.log(`${this.meno} šteka.`);
      }
    }
    
    // Vytvorenie inštancie podtriedy
    const môjPes = new Pes('Bublik', ['Labrador', 'Collie']);
    
    // Volanie metód z oboch tried
    môjPes.hovorí(); // Výstup: Bublik vydáva zvuk.
    môjPes.šteka();  // Výstup: Bublik šteka.
    
    // Prototyp `Pes.prototype` je `Zviera.prototype`
    console.log(Object.getPrototypeOf(môjPes) === Pes.prototype); // true
    
    // Prototyp `Pes.prototype` je `Zviera.prototype`
    console.log(Object.getPrototypeOf(Pes.prototype) === Zviera.prototype); // true
    

Kľúčové koncepty:

  • Reťazec prototypov: Väzba medzi objektmi cez ich [[Prototype]].

  • __proto__ (zastaralé/nestandardné, ale užitočné pre pochopenie): Vlastnosť, cez ktorú je možné získať prístup k [[Prototype]]. Neodporúča sa používať v produkčnom kóde.

  • Object.getPrototypeOf(obj): Štandardný spôsob, ako získať prototyp objektu.

  • Object.setPrototypeOf(obj, proto): Štandardný spôsob, ako zmeniť prototyp objektu (neodporúča sa meniť prototypy u už existujúcich objektov po ich vytvorení).

  • instanceof: Operátor na kontrolu, či je objekt inštanciou triedy alebo konštrukčnej funkcie, cez kontrolu jeho reťazca prototypov.

    console.log(môjPes instanceof Pes);   // true
    console.log(môjPes instanceof Zviera); // true
    console.log(môjPes instanceof Object); // true (na konci reťazca je `Object.prototype`)
    
  • super: Používa sa v triedach na volanie metód alebo konštruktora rodičovskej triedy.

Rozdiel medzi klasickým a triednym prístupom: Triedy poskytujú štruktúrovanejší a syntakticky pohodlnejší spôsob práce s prototypovým dedičstvom, podobne ako v iných programovacích jazykoch. Avšak základný mechanizmus zostáva rovnaký — dedičstvo cez prototypy.