Sobes.tech
Junior

Magyarázd el, hogyan működik az öröklődés a JavaScriptben.

sobes.tech MI

Válasz az MI-től

A JavaScript-ben az öröklődés prototípusokon keresztül valósul meg. Minden JavaScript-objektumnak van egy belső [[Prototype]] tulajdonsága, amely egy másik objektumra mutat. Amikor hozzáférést próbálunk kérni egy olyan tulajdonsághoz vagy metódushoz, amely nem közvetlenül az adott objektumban található, a JavaScript motor megkeresi ezt a tulajdonságot vagy metódust az objektum prototípusában. Ha nem találja ott, akkor folytatja a keresést a prototípus lánc mentén, amely a [[Prototype]] kapcsolatokból áll, amíg el nem éri a null-t (a lánc végét).

Két fő öröklődési mechanizmus létezik:

  1. Klasszikus prototípus alapú öröklődés (ES5 és korábban): Konstrukciós függvények és azok prototype tulajdonságának használatán alapul.

    // Konstrukciós függvény
    function Állat(név) {
      this.név = név;
    }
    
    // Metódus hozzáadása a prototípushoz
    Állat.prototype.szól = function() {
      console.log(`${this.név} hangot ad ki.`);
    };
    
    // Példány létrehozása
    const kutya = new Állat('Kutya');
    
    // Metódus hívása a prototípusból
    kutya.szól(); // Kimenet: Kutya hangot ad ki.
    
    // A `dog` példány prototípusa az `Állat.prototype`
    console.log(Object.getPrototypeOf(kutya) === Állat.prototype); // true
    
  2. Osztály alapú öröklődés (ES6 és később): A class és extends szintaxist használja, amely a háttérben továbbra is prototípusokat használ.

    // Alap osztály
    class Állat {
      constructor(név) {
        this.név = név;
      }
    
      szól() {
        console.log(`${this.név} hangot ad ki.`);
      }
    }
    
    // Alosztály, amely az Állat-ból örököl
    class Kutya extends Állat {
      constructor(név, fajták) {
        super(név); // Szülő osztály konstruktorának hívása
        this.fajták = fajták;
      }
    
      ugat() {
        console.log(`${this.név} ugat.`);
      }
    }
    
    // Példány létrehozása az alosztályból
    const az énKutyám = new Kutya('Bublik', ['Labrador', 'Collie']);
    
    // Metódusok hívása mind az Állat, mind a Kutya osztályból
    az énKutyám.szól(); // Kimenet: Bublik hangot ad ki.
    az énKutyám.ugat();  // Kimenet: Bublik ugat.
    
    // A példány prototípusa a `Kutya.prototype`
    console.log(Object.getPrototypeOf(az énKutyám) === Kutya.prototype); // true
    
    // A `Kutya.prototype` prototípusa az `Állat.prototype`
    console.log(Object.getPrototypeOf(Kutya.prototype) === Állat.prototype); // true
    

Fő fogalmak:

  • Prototípus lánc: Az objektumok közötti kapcsolat a [[Prototype]]-en keresztül.

  • __proto__ (elavult/nem szabványos, de hasznos a megértéshez): Az a tulajdonság, amelyen keresztül hozzáférhetünk a [[Prototype]]-hez. Nem ajánlott a produkciós kódban használni.

  • Object.getPrototypeOf(obj): A prototípus lekérdezésének szabványos módja.

  • Object.setPrototypeOf(obj, proto): A prototípus módosításának szabványos módja (nem ajánlott meglévő objektumok prototípusának módosítására később).

  • instanceof: Az operátor, amely ellenőrzi, hogy az objektum példánya-e egy osztálynak vagy konstrukciós függvénynek, a prototípus lánc ellenőrzésével.

    console.log(az énKutyám instanceof Kutya);   // true
    console.log(az énKutyám instanceof Állat); // true
    console.log(az énKutyám instanceof Object); // true (a lánc végén az `Object.prototype`)
    
  • super: Osztályokban a szülő osztály metódusainak vagy konstruktorának hívására szolgál.

A klasszikus és az osztály alapú megközelítés közötti különbség: Az osztályok strukturáltabb és szintaktikailag kényelmesebb módot kínálnak a prototípus alapú öröklődés kezelésére, hasonlóan más programozási nyelvekhez. Az alap mechanizmus azonban ugyanaz marad — az öröklődés prototípusokon keresztül.