Sobes.tech
Junior

Обяснете как работи наследяването в JavaScript.

sobes.tech AI

Отговор от AI

Наследяването в JavaScript се базира на прототипи. Всеки обект има вътрешно свойство [[Prototype]] (достъпно чрез __proto__ или Object.getPrototypeOf()), което сочи към друг обект.

Когато се опитваме да достъпим свойство или метод на обект, ако той не е намерен директно в обекта, JavaScript го търси в [[Prototype]] на този обект, след това в [[Prototype]] на прототипа и така нататък по веригата на прототипите, докато не достигне края (Object.prototype), чийто [[Prototype]] е null.

Това е прототипното наследяване.

Класовете в ECMAScript 2015 (ES6) са синтактичен захар над прототипното наследяване. Те предоставят по-удобен синтаксис за работа с прототипи и създаване на йерархии от обекти.

Пример за използване на прототипно наследяване преди ES6:

// Конструктор на родителя
function Animal(name) {
  this.name = name;
}

// Метод на родителя на прототипа
Animal.prototype.sayHi = function() {
  console.log(`Здравей, аз съм ${this.name}`);
};

// Конструктор на потомка
function Dog(name, breed) {
  // Викаме конструктора на родителя
  Animal.call(this, name);
  this.breed = breed;
}

// Настройваме прототипа на потомка да сочи към прототипа на родителя
// Запазваме референцията към конструктора Dog
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// Добавяме метод към потомка
Dog.prototype.bark = function() {
  console.log("Гав-гав!");
};

// Създаваме екземпляр на потомка
const myDog = new Dog("Боби", "Лабрадор");

// Използваме методите на родителя и потомка
myDog.sayHi(); // Изписва: Здравей, аз съм Боби
myDog.bark();  // Изписва: Гав-гав!

Пример за използване на класове (ES6):

// Родителски клас
class Animal {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    console.log(`Здравей, аз съм ${this.name}`);
  }
}

// Дъщерен клас, наследяващ от Animal
class Dog extends Animal {
  constructor(name, breed) {
    // Викаме конструктора на родителя
    super(name);
    this.breed = breed;
  }

  bark() {
    console.log("Гав-гав!");
  }
}

// Създаваме екземпляр на дъщерния клас
const myDog = new Dog("Рекс", "Немска овчарка");

// Използваме методите на родителя и потомка
myDog.sayHi(); // Изписва: Здравей, аз съм Рекс
myDog.bark();  // Изписва: Гав-гав!

Ключови моменти за наследяване в JavaScript:

  • Прототипи: Всеки обект има прототип.
  • Верига на прототипите: При търсене на свойство или метод се обхождат прототипите нагоре по веригата.
  • [[Prototype]]: Вътрешно свойство, сочещо към прототип.
  • __proto__: Застарял, но често използван начин за достъп до [[Prototype]].
  • Object.getPrototypeOf(): Препоръчителен начин за достъп до [[Prototype]].
  • Конструктори и prototype: Преди ES6 се използваха за създаване на обекти и настройване на прототипите им.
  • Класове (ES6): Синтактичен захар за прототипното наследяване, използващ ключовите думи class, extends, super.