Гид по технологиям

Классы JavaScript: конструкторы, методы, static

7 min read JavaScript Обновлено 31 Dec 2025
Классы JavaScript: конструктор, методы, static
Классы JavaScript: конструктор, методы, static

Программист за компьютером, пишущий код и работающий с JavaScript

Что такое класс в JavaScript

Класс — это шаблон (blueprint) для создания объектов с общими свойствами и методами. Внутри класса вы обычно определяете конструктор и методы. В ES6 классы были добавлены как более привычный синтаксис для разработчиков, привыкших к объектно-ориентированному стилю (например, Java или C++), но под капотом они всё ещё работают через прототипы.

Определение в одну строку: класс — именованная конструкция для создания объектов с предопределёнными полями и поведением.

Важно: ключевое слово class обязательно для объявления класса. Без него код, написанный в стиле классов, не исполнится как класс.

Общая структура класса

Минимальная форма класса выглядит так:

class ClassName {
  // тело класса
}

Тело класса может содержать:

  • конструктор: инициализирует состояние экземпляра;
  • методы экземпляра: работают с this и данными конкретного объекта;
  • статические методы: вызываются на самом классе, без экземпляра;
  • поля класса (публичные/приватные — современные возможности JS).

Конструктор: зачем и как

Конструктор — это специальный метод с именем constructor. Он вызывается автоматически при создании нового объекта через оператор new. Конструктор задаёт начальные значения полей экземпляра.

Пример конструктора:

class Student {
  constructor(firstName, lastName, startDate) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.startDate = startDate;
  }
}

Ключевые моменты:

  • this указывает на создаваемый экземпляр класса;
  • в JS нет обязательной декларации полей вне конструктора (в отличие от статически типизированных языков);
  • если конструктор не задан, движок создаст пустой конструктор автоматически.

Совет: используйте const для переменных, которым не требуется переназначение, например const john = new Student(…).

Создание экземпляра

Чтобы создать объект (экземпляр класса), используйте new:

const john = new Student('John', 'Brown', 2018);

new выполняет три шага в упрощённом виде:

  1. Создаёт пустой объект.
  2. Привязывает объект к прототипу класса.
  3. Вызывает constructor, где this указывает на вновь созданный объект.

Без переменной, на которую ссылается экземпляр, вы не сможете использовать его методы и свойства позже.

Методы экземпляра

Метод — это функция, объявленная внутри класса, которая оперирует данными конкретного объекта.

Пример метода report:

class Student {
  constructor(firstName, lastName, startDate) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.startDate = startDate;
  }

  report() {
    return `${this.firstName} ${this.lastName} started attending this institution in ${this.startDate}`;
  }
}

Вызов метода:

const john = new Student('John', 'Brown', 2018);
let result = john.report();
console.log(result);
// Выведет: John Brown started attending this institution in 2018

Заметки по методам:

  • Методы экземпляра имеют доступ к this.
  • Не используйте стрелочные функции для методов, если нужен this, привязанный к экземпляру: стрелочная функция захватывает лексическое this и может вести себя не так, как ожидается.

Статические методы

Статические методы объявляются с ключевым словом static. Их можно вызывать напрямую на классе, без создания экземпляра.

Пример:

class Student {
  constructor(firstName, lastName, startDate) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.startDate = startDate;
  }

  report() {
    return `${this.firstName} ${this.lastName} started attending this institution in ${this.startDate}`;
  }

  static endDate(startDate) {
    return startDate + 4;
  }
}

console.log(Student.endDate(2018)); // 2022

Статические методы полезны для фабричных функций, утилит и логики, не зависящей от конкретного состояния экземпляра.

Современные расширения классов

В современных версиях JavaScript доступны дополнительные возможности для классов:

  • публичные поля: можно объявлять поля вне конструктора;
  • приватные поля: синтаксис с #, например #password;
  • статические поля;
  • геттеры и сеттеры через get/set.

Пример приватного поля:

class User {
  #password;
  constructor(name, password) {
    this.name = name;
    this.#password = password;
  }

  checkPassword(value) {
    return value === this.#password;
  }
}

Важно: приватные поля недоступны извне и не входят в прототип.

Когда классы не подходят — альтернативы

Классы удобны, но не всегда оптимальны. Рассмотрите альтернативы:

  1. Фабричные функции (factory functions). Просты и гибки.
function createStudent(firstName, lastName, startDate) {
  return {
    firstName,
    lastName,
    startDate,
    report() {
      return `${this.firstName} ${this.lastName} started in ${this.startDate}`;
    }
  };
}
  1. Композиция вместо наследования (compose over inherit). Вместо длинной иерархии классов собирайте объекты из независимых частей.

  2. Прототипное наследование напрямую, если нужно тонко управлять прототипами.

Когда классы плохо работают:

  • когда нужно лёгкое объединение поведения (mixins могут вызывать сложности);
  • при необходимости низкоуровневого контроля цепочки прототипов;
  • в функционально-ориентированных кодовых базах, где предпочтительна иммутабельность.

Частые ошибки и подводные камни

  • Использование стрелочной функции для метода, когда нужен собственный this.
  • Переопределение прототипных методов неправильно — теряются контракты.
  • Попытка вызвать метод экземпляра на классе и наоборот.
  • Ожидание, что поля будут объявлены заранее: в JS поля обычно создают внутри конструктора или объявляют как публичные поля.
  • Неправильная работа с приватными полями (#) при попытке доступиться к ним извне.

Тестирование и критерии приёмки

Критерии приёмки для простого класса Student:

  • Конструктор корректно сохраняет firstName, lastName и startDate.
  • Метод report возвращает строку с корректными данными.
  • Статический метод endDate возвращает startDate + 4.
  • Приватные поля (если используются) недоступны извне.

Пример тестов (простая схема):

  • Создать экземпляр с известными значениями.
  • Проверить поля экземпляра.
  • Вызвать report и сравнить со строкой-ожиданием.
  • Вызвать Student.endDate(2018) и проверить результат 2022.

Рольовые чек-листы

Для разработчика:

  • Выбрал ли я класс или фабрику и почему?
  • Описал ли конструктор все необходимые поля?
  • Не использую ли я стрелочные функции там, где нужен this?
  • Добавлены ли тесты и комментарии?

Для ревьювера:

  • Соответствует ли API класса требованиям?
  • Есть ли побочные эффекты в конструкторах?
  • Правильно ли используются приватные поля?
  • Есть ли автотесты с граничными значениями?

Для QA:

  • Тесты на создание/удаление объектов.
  • Тесты на корректность методов и статических утилит.
  • Проверка поведения при некорректных входных данных.

Ментальные модели и эвристики

  • Класс как строительный чертёж: одинаковая структура, разные экземпляры.
  • this как «этот конкретный дом», построенный по чертежу.
  • Static как инструмент класса, а не отдельного дома (например, калькулятор сроков строительства).
  • Композиция лучше наследования, когда поведение трудно разделить по уровням.

Совместимость и миграция

  • Классы появились в ES6 (2015). Поддержка современных браузеров есть, но для старых окружений используют транспайлеры (Babel) и полифилы.
  • Если проект поддерживает старые среды — используйте транспиляцию или фабрики.
  • Приватные поля (#) поддерживаются в современных движках; для совместимости используйте условные альтернативы (символы, замыкания).

Безопасность и защита данных

  • Не храните в открытых полях чувствительные данные (пароли, токены). Используйте приватные поля или внешнее хранилище.
  • Методы должны проверять входные данные и не доверять внешнему вводу.
  • Следите за сериализацией объектов: JSON.stringify не включает приватные поля и методы.

Примеры расширенного использования

Ниже — дополнительные примеры шаблонов и паттернов.

Фабрика с приватными данными через замыкание:

function createCounter() {
  let count = 0; // приватно
  return {
    increment() { return ++count; },
    get() { return count; }
  };
}

const c = createCounter();
console.log(c.increment()); // 1

Класс с геттером и сеттером:

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  get area() {
    return this.width * this.height;
  }

  set size({ width, height }) {
    this.width = width;
    this.height = height;
  }
}

Mixins (комбинация поведения) — осторожно с конфликтами имён:

const CanEat = Base => class extends Base {
  eat() { console.log('eating'); }
};

class Animal {}
class Dog extends CanEat(Animal) {}

Руководство по внедрению класса (SOP)

  1. Сформулируйте ответственность класса — одна обязанность.
  2. Определите поля и публичный API (методы).
  3. Решите: нужны ли приватные поля/методы.
  4. Реализуйте конструктор и методы.
  5. Напишите unit-тесты на поведение и граничные случаи.
  6. Сделайте code review и проверку стиля.
  7. Документируйте использование класса.

Факты и ориентиры

  • ES6 (включая синтаксис class) был принят в 2015 году.
  • Статические методы вызываются на классе, а методы экземпляра — на объекте.
  • Приватные поля помечаются символом # и недоступны извне.

Частые сценарии использования

  • Моделирование предметной области (домены): User, Order, Product.
  • Утилиты и фабрики: DateUtils как статический набор функций.
  • Инкапсуляция состояния с методами для управления этим состоянием.

Примеры тест-кейсов и критерии приёмки

Тест-кейсы:

  • Создание экземпляра с валидными данными и проверка полей.
  • Вызов метода report и валидация строки-результата.
  • Попытка доступиться к приватному полю — должно быть недоступно.
  • Проверка статического метода на корректный результат.

Критерии приёмки:

  • Все тесты зеленые.
  • Код покрыт минимум на уровне, требуемом командой (например, 70% — параметр команды).
  • Нет утечек памяти при массовом создании/удалении экземпляров.

Глоссарий (одной строкой)

  • Класс: шаблон для создания объектов.
  • Экземпляр: объект, созданный по классу.
  • Конструктор: метод, инициализирующий экземпляр.
  • this: ссылка на текущий экземпляр.
  • Статический метод: функция на уровне класса.

Часто задаваемые вопросы

Нужно ли всегда использовать class?

Нет. Для простых объектов и функциональных паттернов фабрики часто проще и гибче.

Чем private-поля (#) отличаются от обычных полей?

#-поля полностью скрыты извне и не попадают в прототип; обычные поля доступны и перечисляемы.

Как обеспечить совместимость с устаревшими браузерами?

Используйте транспайлер (Babel) и настройку целевых окружений.

Краткое резюме

  • Классы в JavaScript делают код более декларативным и знакомым для OOP-разработчиков.
  • Под капотом классы всё ещё используют прототипы.
  • Выбирайте между классами и фабриками, исходя из требований к модульности и совместимости.
  • Покрывайте классы тестами и следуйте принципам единой ответственности.

Важно: практика и чтение исходного кода помогут понять тонкости поведения классов в реальных проектах.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Переход с Microsoft Office на WPS Office
Офисное ПО

Переход с Microsoft Office на WPS Office

Как изменить цвет текста с помощью CSS
Веб-разработка

Как изменить цвет текста с помощью CSS

CSS тени: box-shadow и text-shadow
CSS

CSS тени: box-shadow и text-shadow

Как встроить MP3 на сайт — HTML5, Google Drive, CMS
Веб

Как встроить MP3 на сайт — HTML5, Google Drive, CMS

Начать сайт с HTML5 Boilerplate — быстрое руководство
Веб-разработка

Начать сайт с HTML5 Boilerplate — быстрое руководство

Как обновиться до Windows 10 Mobile
Мобильные ОС

Как обновиться до Windows 10 Mobile