Привет, меня зовут Саша, и я разрабатываю на JavaScript. В прошлый раз мы разбирались с методами объектов и идентификатором this, научившись делать объекты по-настоящему живыми и независимыми.

Сегодня двинемся дальше. Покажу, как создавать множество однотипных объектов, не копируя код раз за разом. Мы разберемся с функциями-конструкторами и оператором new — тем самым фундаментом, на котором строятся современные классы в JavaScript. Как всегда, расскажу все доступно и просто, поехали!

Функции для создания объектов

Прежде чем пойдем дальше, советую глянуть прошлую статью о методах объектов и загадочном слове this. Там я объяснил, зачем все это нужно и как работает изнутри. Если база про this уже есть в голове, будет гораздо проще понять, как мы проектируем сложные структуры здесь.

В JavaScript объекты в комбинации с массивами — мощный инструмент для проектирования сложных структур. Они хранят не только информацию, но и методы для работы с ней. Давайте посмотрим на массив объектов пользователей:

const users = [
 {
   name: "Анна",
   age: 25,
   greet() {
     console.log(Привет, я ${this.name}!);
   },
 },
 {
   name: "Петр",
   age: 30,
   greet() {
     console.log(Привет, я ${this.name}!);
   },
 },
 {
   name: "Илья",
   age: 19,
   greet() {
     console.log(Привет, я ${this.name}!);
   },
 },
];

users.forEach((user) => user.greet());
Результат в консоли.
Результат в консоли.

Код работает, но присмотримся к объектам пользователей. Заметили проблему? Мы постоянно переписываем один и тот же метод greet для каждого нового пользователя. Сейчас их всего три, но представьте, что их будет 100 или 1 000. Такой ручной подход явно не подходит для масштабирования.

Самое очевидное решение — создать фабричную функцию. Она будет работать как конвейер, штампуя новые объекты по заданному шаблону.

Давайте напишем такую функцию и создадим с ее помощью наш массив пользователей:

// Функция-фабрика для создания пользователей
function createUser(name, age) {
  
 // Создаем новый объект
 const user = {};

 // Заполняем его свойства
 user.name = name;
 user.age = age;

 // Добавляем метод
 user.greet = function () {
   console.log(Привет, я ${this.name}!);
 };

 // Возвращаем готовый объект
 return user;
}

// Теперь создаем массив через фабрику
const users = [
 createUser("Анна", 25),
 createUser("Петр", 30),
 createUser("Илья", 19),
];

users.forEach((user) => user.greet());
Результат в консоли тот же.
Результат в консоли тот же.

Итак, что мы с этого выиграли — теперь у нас есть четкий, единый шаблон. Если нужно добавить новое свойство (например, email) или изменить логику метода, мы делаем это в одном месте, внутри функции createUser. Код стал поддерживаемым, а создание новых пользователей — предсказуемым и быстрым.

Однако в JavaScript есть более мощный и элегантный встроенный механизм для таких задач. Он использует специальный оператор new и превращает обычную функцию в настоящую фабрику объектов с особыми возможностями. Главные его плюсы в том, что он автоматизирует рутину — создание объекта и возврат результата. Давайте разберемся.

Бесплатный базовый курс по JS

Рассказываем, как работать с переменными, типами данных, функциями и о многом другом!

Старт в январе →

Оператор new и функции-конструкторы

Посмотрим, как создавать настоящую фабрику объектов с помощью оператора new. Не буду томить и сразу перейду к примеру, перепишем наш код создания пользователя:

// Это функция-конструктор
// Обратите внимание на заглавную букву — это важное правило!
function User(name, age) {
 this.name = name;
 this.age = age;

 this.greet = function () {
   console.log(Привет, я ${this.name}!);
 };

 // return не нужен — все происходит автоматически!
}

// Создаем пользователей с помощью new
const users = [
 new User("Анна", 25),
 new User("Петр", 30),
 new User("Илья", 19),
];

users.forEach((user) => user.greet());


Результат в консоли тот же.
Результат в консоли тот же.

Посмотрите внимательно, теперь мы не создаем пустой объект вручную внутри функции. Вместо этого мы сразу обращаемся к нему через this. И это ключевое отличие. Оператор new создает за нас новый объект и передает его в функцию через this. Мы как бы говорим: «new, создай новый объект и дай мне на него ссылку (this), чтобы я его настроил».

Оператор new — это специальный механизм JavaScript, который превращает обычную функцию в фабрику объектов. 

Когда вы вызываете функцию с new, происходит следующее:

  1. создается новый пустой объект;

  2. this внутри функции начинает ссылаться на этот новый объект;

  3. выполняется код функции (обычно она добавляет свойства в this);

  4. функция автоматически возвращает этот новый объект (если явно не возвращает что-то другое).

А что такое функция-конструктор? Это просто функция, которую вы задумали вызывать с оператором new. Ее задача инициализировать новый объект, наполняя this свойствами и методами. 

Кстати, что бы по названию функции сразу было понятно, что это конструктор, существует соглашение называть с заглавной буквы (как User).

Почему функции-конструкторы — это хорошо

Они дают нам четкий, стандартный способ создавать однотипные объекты. Код становится предсказуемым: видите new User(), сразу понимаете, что создается новый пользователь.

Еще, это родной для JavaScript подход, который открывает доступ к мощной системе прототипов, помогающей одним объектам заимствовать свойства и методы у других.

Такие функции органично встраиваются в логику языка. Например, встроенные объекты вроде Date или Array создаются именно через конструкторы. Это не просто паттерн, а фундаментальная часть JavaScript, которая, как мы увидим позже, лежит в основе современных классов.

Оператор new — очень удобный в использовании инструмент. А для закрепления теории предлагаю далее разобрать небольшой пример.

Пример с товарами в магазине

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

// Конструктор для товаров
function Product(name, price, discountPercent) {
 this.name = name;
 this.price = price;
 this.discountPercent = discountPercent; // Скидка в процентах, например 10

 // Метод для расчета цены со скидкой
 this.getFinalPrice = function () {
   const discountAmount = this.price * (this.discountPercent / 100);
   return this.price - discountAmount;
 };

 // Метод для вывода информации о товаре
 this.logInfo = function () {
   const finalPrice = this.getFinalPrice();
   console.log(${this.name});
   console.log(  Цена: ${this.price} руб.);
   console.log(  Скидка: ${this.discountPercent}%);
   console.log(  Итог: ${finalPrice.toFixed(2)} руб.);
   console.log("---");
 };
}

// Создаем массив товаров с помощью new
const products = [
 new Product("Кофе", 600, 10),
 new Product("Чай", 450, 5),
 new Product("Печенье", 150, 15),
];

// Выводим информацию о каждом товаре
products.forEach(product =>  product.logInfo());

let totalWithoutDiscount = 0;
let totalWithDiscount = 0;

// Проходим по всем товарам и суммируем цены
for (const product of products) {
 totalWithoutDiscount += product.price;
 totalWithDiscount += product.getFinalPrice();
}

const totalSaved = totalWithoutDiscount - totalWithDiscount;

console.log(Общая сумма без скидок: ${totalWithoutDiscount} руб.);
console.log(Общая сумма со скидками: ${totalWithDiscount.toFixed(2)} руб.);
console.log(Вы сэкономили: ${totalSaved.toFixed(2)} руб.);
Результат в консоли.
Результат в консоли.

Этот пример отлично показывает мощь функций-конструкторов. Мы создали универсальный шаблон для товаров, который легко масштабировать и поддерживать.

Что особенно важно, вся логика работы с товаром (расчет цены, форматирование вывода) запечатана (инкапсулирована) внутри объекта. Это дает свои преимущества: предсказуемость работы кода, простоту повторного использования и защиту данных от случайных изменений извне.

Итог

Сегодня мы превратили ручное копирование объектов в эффективное производство с помощью функций-конструкторов и оператора new. Вы научились создавать универсальные шаблоны, где вся логика заперта внутри.

Еще раз коротко вспомним, как работает new с функциями: он автоматически создает объект, связывает его с this и возвращает результат. 

Запомните правило: конструкторы пишут с большой буквы и вызывают только с new.

Этот фундамент подготовит вас к классам в JavaScript о которых я расскажу в следующей статье. Практикуйтесь, создавая конструкторы для реальных задач. 

Делитесь своими мыслями в комментариях — будет интересно обсудить ваш опыт. В следующем материале мы перейдем к классам и разберем, как они упрощают работу с прототипами. До встречи.

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


  1. js2me
    16.01.2026 09:13

    Спасибо за полезную статью, я бы еще добавил маленький пункт про разницу описания методов через прототип (1 хуже по памяти чем 2 и 3, тк создает каждый раз функцию для поля bar)

    function Foo() {
      this.bar = function() {}
    }
    
    function Foo() {
    }
    
    Foo.prototype.bar = function() {}
    
    class Foo {
      bar() {}
    }



    Последнее время, может быть я ошибаюсь, но большинство разработчиков на JavaScript (особенно на React) почему-то боятся слов class , constructor :)