Основа ООП в JS — прототипная модель (в отличие от классической в Java/C++).
[[Prototype]]
(доступ через __proto__
или методы Object.getPrototypeOf()
).Пример:
const animal = {
eats: true,
walk() {
console.log("Animal walks");
}
};
const rabbit = {
jumps: true,
__proto__: animal // Наследование
};
rabbit.walk(); // "Animal walks" (метод из прототипа)
Механизм поиска свойств по всей иерархии наследования.
const animal = { eats: true };
const rabbit = { __proto__: animal };
const longEar = { __proto__: rabbit };
console.log(longEar.eats); // true (из animal)
Важно: Циклические цепочки запрещены (вызовет ошибку).
Object.create(proto)
: Создает объект с указанным прототипом.
const animal = { eats: true };
const rabbit = Object.create(animal);
Object.getPrototypeOf(obj)
: Возвращает прототип.
Object.setPrototypeOf(obj, proto)
: Устанавливает прототип (медленный, лучше избегать).
До 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"
Синтаксический сахар над прототипами (появился в 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
.Классы — все те же прототипы:
class Animal {}
console.log(typeof Animal); // "function" (все равно функция)
Прототипы:
[[Prototype]]
.Цепочка прототипов:
obj.__proto__
→ parent.__proto__
→ ... → null
.Классы (ES6):
P.S. В Angular классы используются повсеместно (компоненты, сервисы), но важно понимать их прототипную природу.