Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Объектно-ориентированное программирование в JavaScript
Да, есть, но это не классическое ООП
JavaScript поддерживает ООП, но реализует его иначе, чем традиционные языки вроде Java или C++. Это прототипное наследование, а не классовое. Однако с появлением ES6 в 2015 году синтаксис class дает более привычный способ работы с ООП.
Четыре столпа ООП в JavaScript
1. Инкапсуляция
Инкапсуляция — скрытие внутреннего состояния объекта. В JavaScript достигается через замыкания и приватные поля (с ES2022):
class BankAccount {
#balance = 0; // Приватное поле
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 100
console.log(account.#balance); // SyntaxError — приватное!
Вариант со старым синтаксисом через замыкания:
function BankAccount() {
let balance = 0; // Переменная в замыкании
this.deposit = function(amount) {
if (amount > 0) {
balance += amount;
}
};
this.getBalance = function() {
return balance;
};
}
const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 100
console.log(account.balance); // undefined
2. Наследование
Наследование — получение свойств и методов родительского класса. В JavaScript реализуется через прототипное наследование:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + " издает звук");
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // Вызов конструктора родителя
this.breed = breed;
}
speak() {
console.log(this.name + " лает");
}
}
const dog = new Dog("Макс", "лабрадор");
dog.speak(); // "Макс лает"
console.log(dog instanceof Animal); // true
Прототипное наследование работает так:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + " издает звук");
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
console.log(this.name + " лает");
};
const dog = new Dog("Макс", "лабрадор");
dog.speak(); // "Макс лает"
3. Полиморфизм
Полиморфизм — способность объектов разных типов отвечать на один и тот же запрос разными способами:
class Shape {
area() {
throw new Error("Метод должен быть переопределен");
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius ** 2;
}
}
class Square extends Shape {
constructor(side) {
super();
this.side = side;
}
area() {
return this.side ** 2;
}
}
const shapes = [
new Circle(5),
new Square(4),
new Circle(3)
];
shapes.forEach(shape => {
console.log(shape.area());
});
4. Абстракция
Абстракция — скрытие сложности и предоставление упрощенного интерфейса:
class Database {
#connection = null;
connect(url) {
this.#connection = this.#createConnection(url);
}
#createConnection(url) {
// Сложная логика подключения
return { url };
}
query(sql) {
// Для пользователя — просто query(), сложность скрыта
return this.#connection.execute(sql);
}
}
const db = new Database();
db.connect("postgres://...");
db.query("SELECT * FROM users");
Разница между прототипным и классовым наследованием
Прототипное (классическое для JS):
- Основано на копировании свойств от объекта к объекту
- Любой объект может быть прототипом
- Более гибко, но сложнее для понимания
Классовое (ES6):
- Синтаксический сахар над прототипным наследованием
- Привычнее для программистов из других языков
- В реальности все равно использует прототипы
// Это одно и то же
class Person {}
new Person();
// То же самое, но старый синтаксис
function Person() {}
new Person();
Композиция вместо наследования
В современном JavaScript часто используют композицию — комбинирование объектов вместо наследования:
const canEat = {
eat() { console.log("Ем"); }
};
const canWalk = {
walk() { console.log("Хожу"); }
};
const canFly = {
fly() { console.log("Летаю"); }
};
const bird = Object.assign({}, canEat, canWalk, canFly);
bird.eat(); // "Ем"
bird.fly(); // "Летаю"
Итог
JavaScript поддерживает все четыре столпа ООП: инкапсуляцию, наследование, полиморфизм и абстракцию. Правда, реализует их через прототипное наследование, а не через классы (хотя синтаксис ES6 class скрывает эту сложность). Выбор между наследованием и композицией зависит от конкретной задачи.