Прототипы и наследование
↑ 2.1 JavaScript: продвинутый · ← Предыдущая · → Следующая
Зачем это на собесе
«Как работает наследование в 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)— «чистый словарь».
Практика
- Постройте цепочку
Animal → Dogбезclassи проверьтеinstanceof. - Реализуйте свой
newиinstanceof. - Найдите на схеме цепочку прототипов для массива и функции.
Вопросы с ответами
Как работает наследование в JavaScript?
Через цепочку прототипов: при отсутствии свойства у объекта поиск продолжается в его прототипе и выше.
Что делает оператор
new?Создаёт объект с прототипом конструктора, вызывает конструктор с этим
thisи возвращает объект.
Чем
__proto__отличается отprototype?
__proto__— ссылка на прототип у экземпляра,prototype— свойство функции-конструктора, становящееся прототипом экземпляров.