Sobes.tech
Junior

Wyjaśnij, jak działa dziedziczenie w JavaScript.

sobes.tech AI

Odpowiedź od AI

Dziedziczenie w JavaScript opiera się na prototypach. Każdy obiekt ma własność wewnętrzną [[Prototype]] (dostępną przez __proto__ lub Object.getPrototypeOf()), która wskazuje na inny obiekt.

Przy próbie dostępu do właściwości lub metody obiektu, jeśli nie zostanie ona znaleziona bezpośrednio w obiekcie, JavaScript szuka jej w [[Prototype]] tego obiektu, następnie w [[Prototype]] prototypu i tak dalej w łańcuchu prototypów, aż do końca (Object.prototype), którego [[Prototype]] jest null.

To jest dziedziczenie oparte na prototypach.

Klasy w ECMAScript 2015 (ES6) są cukrem składniowym nad dziedziczeniem prototypowym. Zapewniają bardziej przyjazną składnię do pracy z prototypami i tworzenia hierarchii obiektów.

Przykład użycia dziedziczenia prototypowego przed ES6:

// Konstruktor rodzica
function Animal(name) {
  this.name = name;
}

// Metoda rodzica na prototypie
Animal.prototype.sayHi = function() {
  console.log(`Cześć, jestem ${this.name}`);
};

// Konstruktor potomka
function Dog(name, breed) {
  // Wywołanie konstruktora rodzica
  Animal.call(this, name);
  this.breed = breed;
}

// Ustawienie prototypu potomka na prototyp rodzica
// Zachowując odwołanie do konstruktora Dog
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// Dodanie metody potomka
Dog.prototype.bark = function() {
  console.log("Hau-hau!");
};

// Tworzenie instancji potomka
const myDog = new Dog("Boby", "Labrador");

// Użycie metod rodzica i potomka
myDog.sayHi(); // Wyjście: Cześć, jestem Boby
myDog.bark();  // Wyjście: Hau-hau!

Przykład użycia klas (ES6):

// Klasa rodzica
class Animal {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    console.log(`Cześć, jestem ${this.name}`);
  }
}

// Klasa potomna dziedzicząca po Animal
class Dog extends Animal {
  constructor(name, breed) {
    // Wywołanie konstruktora rodzica
    super(name);
    this.breed = breed;
  }

  bark() {
    console.log("Hau-hau!");
  }
}

// Tworzenie instancji klasy potomnej
const myDog = new Dog("Rex", "Owczarek niemiecki");

// Użycie metod rodzica i potomka
myDog.sayHi(); // Wyjście: Cześć, jestem Rex
myDog.bark();  // Wyjście: Hau-hau!

Kluczowe punkty dziedziczenia w JavaScript:

  • Prototypy: Każdy obiekt ma prototyp.
  • Łańcuch prototypów: Poszukiwanie właściwości lub metody przebiega w górę łańcucha prototypów.
  • [[Prototype]]: Właściwość wewnętrzna wskazująca na prototyp.
  • __proto__: Przestarzały, ale często używany sposób dostępu do [[Prototype]].
  • Object.getPrototypeOf(): Zalecany sposób dostępu do [[Prototype]].
  • Konstruktory i prototype: Używane przed ES6 do tworzenia obiektów i ustawiania ich prototypów.
  • Klasy (ES6): Syntaktyczny cukier nad dziedziczeniem prototypowym, używający słów kluczowych class, extends, super.