Jak naprawdę działa dziedziczenie w JavaScript?

Dziedziczenie w JavaScript jest mechanizmem, dzięki któremu obiekty mogą dziedziczyć właściwości i metody od innych obiektów. Jest to kluczowy aspekt prototypowego modelu dziedziczenia w JavaScript, który różni się od klasycznego modelu dziedziczenia stosowanego w wielu innych językach programowania. W JavaScript, dziedziczenie jest realizowane za pomocą łańcuchów prototypów.

Przykład dziedziczenia w JavaScript z użyciem HTML

W poniższym przykładzie stworzymy prostą strukturę dziedziczenia, gdzie Vehicle jest bazowym obiektem, a Car jest obiektem dziedziczącym po Vehicle. Dodatkowo, zaprezentujemy wyniki w prostym dokumencie HTML.

<!DOCTYPE html>
<html>
<head>
    <title>Dziedziczenie w JavaScript</title>
</head>
<body>
    <script>
        // Bazowy obiekt Vehicle
        function Vehicle(brand) {
            this.brand = brand;
        }

        // Metoda dla Vehicle
        Vehicle.prototype.displayBrand = function() {
            console.log("Marka pojazdu: " + this.brand);
        };

        // Obiekt Car dziedziczący po Vehicle
        function Car(brand, model) {
            Vehicle.call(this, brand);
            this.model = model;
        }

        // Ustawienie prototypu Car do dziedziczenia po Vehicle
        Car.prototype = Object.create(Vehicle.prototype);
        Car.prototype.constructor = Car;

        // Dodanie metody do Car
        Car.prototype.displayModel = function() {
            console.log("Model: " + this.model);
        };

        // Tworzenie obiektu Car
        let myCar = new Car("Ford", "Mustang");

        // Wywołanie metod
        myCar.displayBrand(); // Wyświetla markę
        myCar.displayModel(); // Wyświetla model
    </script>
</body>
</html>

Wprowadzenie klas w ES6 (ECMAScript 2015) znacząco uproszczone i ujednolicone tworzenie i zarządzanie obiektami w JavaScript. Chociaż klasy w JavaScript mogą wydawać się podobne do tych znanych z języków bazujących na klasach, takich jak Java czy C#, w rzeczywistości są one “syntactic sugar” nad istniejącym mechanizmem prototypów. Dziedziczenie oparte na klasach w JavaScript jest więc realizowane za pomocą prototypów, a klasy pomagają jedynie w jego bardziej przejrzystym zapisie.

Przykład dziedziczenia z użyciem klas i prototypów

Zobaczmy, jak możemy zaimplementować dziedziczenie w JavaScript, korzystając z klas, ale pamiętając o tym, że pod spodem są to prototypy.

Struktura kodu HTML i JavaScript

W tym przykładzie utworzymy klasę Vehicle i klasę Car, gdzie Car dziedziczy po Vehicle. Pokażemy, jak można wykorzystać klasy do zdefiniowania i dziedziczenia właściwości oraz metod.

<!DOCTYPE html>
<html>
<head>
    <title>Dziedziczenie klas w JavaScript</title>
</head>
<body>
    <script>
        // Definicja klasy bazowej Vehicle
        class Vehicle {
            constructor(brand) {
                this.brand = brand;
            }

            // Metoda wyświetlająca markę pojazdu
            displayBrand() {
                console.log("Marka pojazdu: " + this.brand);
            }
        }

        // Definicja klasy Car, dziedziczącej po Vehicle
        class Car extends Vehicle {
            constructor(brand, model) {
                super(brand); // Wywołanie konstruktora klasy bazowej
                this.model = model;
            }

            // Metoda wyświetlająca model samochodu
            displayModel() {
                console.log("Model: " + this.model);
            }
        }

        // Tworzenie instancji klasy Car
        let myCar = new Car("Ford", "Mustang");

        // Wywołanie metod
        myCar.displayBrand(); // Wyświetla markę
        myCar.displayModel(); // Wyświetla model
    </script>
</body>
</html>

W tym przykładzie Vehicle jest klasą bazową, która definiuje właściwość brand oraz metodę displayBrand. Klasa Car dziedziczy po Vehicle, rozszerzając ją o właściwość model i dodając metodę displayModel. Wywołanie super(brand) w konstruktorze klasy Car jest niezbędne do prawidłowego wywołania konstruktora klasy bazowej i inicjalizacji właściwości brand.

Jak to działa “pod spodem”?

Chociaż używamy składni klas, JavaScript wciąż wykorzystuje prototypy do realizacji dziedziczenia. Gdy tworzymy instancję klasy Car przy użyciu słowa kluczowego new, JavaScript automatycznie ustawia prototyp nowo utworzonego obiektu (myCar.__proto__) na prototyp klasy Car.prototype, który z kolei ma swój prototyp ustawiony na Vehicle.prototype. To właśnie łańcuch prototypów umożliwia dostęp do metod zdefiniowanych w klasie bazowej.

Podsumowanie

Klasy w JavaScript upraszczają składnię dziedziczenia i interakcję z prototypami, oferując bardziej zrozumiały i łatwy w utrzymaniu sposób definiowania obiektów i hierarchii dziedziczenia. Jednak podstawą mechanizmu dziedziczenia w JavaScript pozostają prototypy, co jest ważne do zrozumienia, aby w pełni wykorzystać możliwości języka

Jeżeli chcesz przyśpieszyć swoją naukę tworzenia stron chciałbym polecić mój kurs video JavaScript w którym nauczysz się tego języka od podstaw do zaawansowanych jego aspektów.

Scroll to Top