← Назад к вопросам

Как в JS устроено наследование?

2.3 Middle🔥 251 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Наследование в JavaScript

В JavaScript существует два подхода к наследованию: прототипное наследование (Prototype-based) и классы (синтаксический сахар над прототипами). Оба основаны на одном механизме, но классы предоставляют более знакомый синтаксис для разработчиков, привыкших к языкам с классическим ООП.

Прототипное наследование (Classical approach)

Каждый объект в JavaScript имеет внутреннее свойство [[Prototype]], которое можно явно установить через Object.create() или конструктор с new:

const animal = {
  speak() { console.log("Sound"); }
};

const dog = Object.create(animal);
dog.name = "Rex";
dog.speak(); // "Sound" — наследовано от animal

Или через конструктор:

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

Animal.prototype.speak = function() {
  console.log(this.name + " makes a sound");
};

function Dog(name) {
  Animal.call(this, name); // вызов родителя
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

const dog = new Dog("Rex");
dog.speak(); // "Rex makes a sound"

Классы (Modern approach)

ES6 классы — это синтаксический сахар над прототипным наследованием. Они делают код понятнее и безопаснее:

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

  speak() {
    console.log(this.name + " makes a sound");
  }
}

class Dog extends Animal {
  speak() {
    super.speak(); // вызов метода родителя
    console.log(this.name + " barks!");
  }
}

const dog = new Dog("Rex");
dog.speak();
// "Rex makes a sound"
// "Rex barks!"

Цепочка прототипов (Prototype chain)

Когда вы обращаетесь к методу объекта, JavaScript ищет его в порядке:

  1. На самом объекте
  2. На его [[Prototype]]
  3. На прототипе прототипа (и так вверх)
  4. Пока не найдёт или не достигнет null (конец цепи)
dog.name; // найдено на dog
dog.speak(); // найдено на Animal.prototype
dog.toString(); // найдено на Object.prototype

Ключевые отличия

  • Прототипное: переиспользуешь объекты как прототипы, гибко, но сложнее
  • Классы: знакомый синтаксис, читаемость, лучше для больших проектов
  • Оба работают одинаково под капотом — классы компилируются в прототипное наследование

Современный стандарт рекомендует использовать классы, так как они безопаснее и понятнее.

Как в JS устроено наследование? | PrepBro