Объясните, как работает наследование прототипов, что такое цепочка прототипов, и когда появилось ключевое слова class в JS?angular-8

1. Прототипное наследование

Основа ООП в JS — прототипная модель (в отличие от классической в Java/C++).

Как это работает:

  • Каждый объект имеет скрытое свойство [[Prototype]] (доступ через __proto__ или методы Object.getPrototypeOf()).
  • При обращении к свойству/методу, если его нет в объекте, JS ищет его в прототипе (рекурсивно).

Пример:

const animal = {
  eats: true,
  walk() {
    console.log("Animal walks");
  }
};

const rabbit = {
  jumps: true,
  __proto__: animal // Наследование
};

rabbit.walk(); // "Animal walks" (метод из прототипа)

2. Цепочка прототипов

Механизм поиска свойств по всей иерархии наследования.

Пример цепочки:

const animal = { eats: true };
const rabbit = { __proto__: animal };
const longEar = { __proto__: rabbit };

console.log(longEar.eats); // true (из animal)

Важно: Циклические цепочки запрещены (вызовет ошибку).

3. Методы для работы с прототипами

  • Object.create(proto): Создает объект с указанным прототипом.

    const animal = { eats: true };
    const rabbit = Object.create(animal);
    
  • Object.getPrototypeOf(obj): Возвращает прототип.

  • Object.setPrototypeOf(obj, proto): Устанавливает прототип (медленный, лучше избегать).

4. Функции-конструкторы

До ES6 использовались функции для создания "классов":

function Animal(name) {
  this.name = name;
}

Animal.prototype.walk = function() {
  console.log(`${this.name} walks`);
};

const rabbit = new Animal("Rabbit");
rabbit.walk(); // "Rabbit walks"

5. Классы

Синтаксический сахар над прототипами (появился в ES2015).

Пример:

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

  walk() {
    console.log(`${this.name} walks`);
  }
}

class Rabbit extends Animal {
  jump() {
    console.log(`${this.name} jumps`);
  }
}

const rabbit = new Rabbit("Bugs");
rabbit.walk(); // Наследуется от Animal

Отличия от старых подходов:

  • Более читаемый синтаксис.
  • super() для вызова родительского конструктора.
  • Статические методы через static.

6. Под капотом классов

Классы — все те же прототипы:

class Animal {}
console.log(typeof Animal); // "function" (все равно функция)

Резюмируем

  1. Прототипы:

    • Объекты наследуют свойства через [[Prototype]].
    • Поиск идет по цепочке прототипов.
  2. Цепочка прототипов:

    • Автоматический механизм поиска свойств.
    • obj.__proto__parent.__proto__ → ... → null.
  3. Классы (ES6):

    • Синтаксический сахар для удобства.
    • Под капотом — те же функции-конструкторы и прототипы.

P.S. В Angular классы используются повсеместно (компоненты, сервисы), но важно понимать их прототипную природу.