Если и есть что-то верное в отношении JavaScript, так это то, что существует множество различных способов создания объектов. Фабричная функция — это один из шаблонов, который можно использовать для создания нескольких похожих объектов.

Давайте посмотрим на фабричные функции.

Что такое фабричная функция?

Фабричная функция — это шаблон создания. Это просто функция, которая возвращает объект. Из этого описания довольно очевидно, почему это один из шаблонов, который используется, когда необходимо создать несколько объектов. Здесь у нас есть фабричная функция, которая создает новых пользователей.

Функция настроена так, что мы можем передать имя и фамилию пользователя. Эти два параметра используются для установки свойств объекта, и этот объект возвращается. Кроме того, в объект включен метод fullName, поэтому каждый пользовательский объект будет иметь доступ к этому методу.

user1.fullName(); // 'Steven Hancock'

Теперь эту функцию можно использовать для создания любого количества пользовательских объектов; отсюда и название фабричной функции.

Преимущества заводских функций

Когда у нас есть сложная логика, и нам нужно снова и снова создавать несколько объектов, которые разделяют эту сложную логику, использование шаблона для создания объектов является важной частью нашего кода. Но зачем использовать фабричную функцию вместо функции-конструктора или синтаксиса класса? Оба этих шаблона могут делать одно и то же.

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

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

Закрытие с помощью заводских функций

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

Начальное значение было присвоено переменной initLevel в фабричной функции. Это не часть объекта. Но любой возвращаемый объект имеет доступ к этой переменной через замыкание.

user1.getUserLevel(); // 9

user2.getUserLevel(); // 11

Еще одно преимущество переменной initLevel заключается в том, что она является частной. Код вне функции не может изменить значение этой переменной. Управление этой переменной доступно только функции.

Использование объектов-прототипов с фабричными функциями

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

Допустим, мы хотим, чтобы в прототипе существовала функция fullName, поскольку она одинакова для каждого из этих объектов. Мы можем настроить объект-прототип, и тогда он будет доступен каждому создаваемому объекту. Хитрость включения прототипа с использованием фабричной функции заключается в использовании Object.create().

Сначала нам нужно создать объект, который будет использоваться в качестве объекта-прототипа. Мы сделали это с objProto. После переменной initLevel мы создаем пользовательский объект, используя Object.create(). Это позволяет нам назначить objProto в качестве прототипа.

После создания пользовательского объекта мы назначаем этому объекту дополнительные свойства. Мы назначили fName, lName и level, а также метод getUserLevel. Наконец, мы возвращаем объект.

Объекты продолжают функционировать так же, но теперь метод fullName находится в прототипе.

user1.getUserLevel(); // 9

user2.fullName(); // 'Adrea Smith'

Заключение

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

Следите за многими другими статьями о JavaScript.

Комментарий ниже, чтобы добавить свои мысли к этой статье.