Объясните, как работает наследование в JavaScript.
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Наследование в JavaScript реализуется через прототипы. Каждый объект в JavaScript имеет внутреннее свойство [[Prototype]], которое ссылается на другой объект. Когда мы пытаемся получить доступ к свойству или методу объекта, которого нет непосредственно у него, движок JavaScript ищет это свойство или метод в прототипе этого объекта. Если он не находит его там, то продолжает поиск по цепочке прототипов, которая образуется связями [[Prototype]], пока не достигнет null (конца цепочки).
Существует два основных механизма наследования:
-
Классическое прототипное наследование (ES5 и ранее): Основано на использовании функций-конструкторов и их свойства
prototype.// Функция-конструктор function Animal(name) { this.name = name; } // Добавляем метод в прототип Animal.prototype.speak = function() { console.log(`${this.name} издает звук.`); }; // Создаем экземпляр const dog = new Animal('Собака'); // Вызываем метод из прототипа dog.speak(); // Выведет: Собака издает звук. // Прототип cat - это Animal.prototype console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true -
Классовое наследование (ES6 и позднее): Использует синтаксический сахар
classиextends, который под капотом всё равно оперирует прототипами.// Базовый класс class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} издает звук.`); } } // Подкласс, наследующий от Animal class Dog extends Animal { constructor(name, breeds) { super(name); // Вызов конструктора родительского класса this.breeds = breeds; } bark() { console.log(`${this.name} лает.`); } } // Создаем экземпляр подкласса const myDog = new Dog('Бублик', ['Лабрадор', 'Колли']); // Вызываем методы как из Animal, так и из Dog myDog.speak(); // Выведет: Бублик издает звук. myDog.bark(); // Выведет: Бублик лает. // Прототип myDog - это Dog.prototype console.log(Object.getPrototypeOf(myDog) === Dog.prototype); // true // Прототип Dog.prototype - это Animal.prototype console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
Ключевые концепции:
-
Прототипная цепочка: Связь между объектами через их
[[Prototype]]. -
__proto__(устаревший/нестандартный, но полезный для понимания): Свойство, через которое можно получить доступ к[[Prototype]]. Не рекомендуется использовать в продакшн-коде. -
Object.getPrototypeOf(obj): Стандартный способ получить прототип объекта. -
Object.setPrototypeOf(obj, proto): Стандартный способ изменить прототип объекта (не рекомендуется для изменения прототипа в уже существующих объектах после их создания). -
instanceof: Оператор для проверки, является ли объект экземпляром класса или функции-конструктора, путём проверки его прототипной цепочки.console.log(myDog instanceof Dog); // true console.log(myDog instanceof Animal); // true console.log(myDog instanceof Object); // true (в конце цепочки Object.prototype) -
super: Используется в классах для вызова методов или конструктора родительского класса.
Разница между классическим и классовым подходами: Классы предоставляют более структурированный и синтаксически удобный способ работы с прототипным наследованием, приближенный к другим языкам программирования. Однако фундаментальный механизм остаётся тем же — наследование через прототипы.