← Назад к вопросам

Есть ли ООП в JavaScript?

1.0 Junior🔥 121 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Объектно-ориентированное программирование в 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 скрывает эту сложность). Выбор между наследованием и композицией зависит от конкретной задачи.

Есть ли ООП в JavaScript? | PrepBro