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

↑ 2.1 JavaScript: продвинутый · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

«Как работает наследование в JS?» — обязательный вопрос. Нужно объяснить цепочку прототипов, а не только class.

Объяснение

Каждый объект имеет скрытую ссылку Prototype (доступна через Object.getPrototypeOf(o) или __proto__). При обращении к свойству движок ищет его в объекте, затем по цепочке прототипов до null.

const animal = { eats: true, walk() { return "walk"; } };
const dog = Object.create(animal);   // прототип dog = animal
dog.barks = true;
dog.eats;                            // true (из прототипа)
dog.hasOwnProperty("eats");          // false; Object.hasOwn(dog, "eats")
Object.getPrototypeOf(dog) === animal;   // true
 
function Person(name) { this.name = name; }
Person.prototype.hi = function () { return `Hi, ${this.name}`; };
const p = new Person("A");            // p.__proto__ === Person.prototype
p instanceof Person;                  // true
ПонятиеСмысл
Prototype / __proto__ссылка объекта на прототип
Function.prototypeобъект, который станет прототипом экземпляров при new
obj.constructorссылка на конструктор
instanceofпроверка наличия Constructor.prototype в цепочке
Shadowingсобственное свойство перекрывает прототипное

Что делает new Foo(): создаёт пустой объект → устанавливает Prototype = Foo.prototype → вызывает Foo с this = объект → возвращает объект (если конструктор не вернул другой объект).

Наследование функциями-конструкторами:

function Student(name, school) { Person.call(this, name); this.school = school; }
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Методы на прототипе разделяются всеми экземплярами (экономия памяти), собственные свойства — у каждого.

Нюансы и подводные камни

  • Изменение __proto__ на лету замедляет оптимизации (используйте Object.create/setPrototypeOf осознанно).
  • Модификация встроенных прототипов (Array.prototype) ломает чужой код.
  • for...in обходит и унаследованные перечисляемые свойства: фильтруйте Object.hasOwn.
  • Методы, вынесенные из объекта, теряют this.
  • Объекты без прототипа: Object.create(null) — «чистый словарь».

Практика

  1. Постройте цепочку Animal → Dog без class и проверьте instanceof.
  2. Реализуйте свой new и instanceof.
  3. Найдите на схеме цепочку прототипов для массива и функции.

Вопросы с ответами

Связанные темы