Шаблон Singleton в ES20XX

Или тому подобное…

Синглтоны действительно плохи, я имею в виду, на самом деле не нужны в JavaScript.

При этом вы можете найти множество аргументов по этой теме, часто приукрашенных красивыми фрагментами Java.

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

Используйте следующее на свой страх и риск.

Объект {}

Сначала давайте посмотрим, почему это не нужно: здесь я могу процитировать только одного авторитета из сообщества JavaScript, Акселя Раушмайера:

Шаблон singleton был изобретен для языков на основе классов, чтобы помочь им реализовать компоненты. […] В таких языках вы не можете напрямую создать компонентный объект, для этого вам нужен класс. [JavaScript] позволяет вам напрямую создавать объекты (являясь одним из немногих языков программирования, которые позволяют вам это делать), и здесь нет необходимости в каких-либо уловках.

Использование голых объектов в ES6 приведет к следующему чанку:

Это наиболее простой способ реализовать этот шаблон. Однако, как указывалось ранее, одноэлементный шаблон имеет больше смысла с классами.

Экземпляр модуля

Решением с ES6 является использование экземпляра c lass с областью действия модуль.

Либо с помощью оператора new внутри модуля и экспорта его как по умолчанию:

Или создав переменную экземпляра null, привязанную к модулю, и назначив ей ключевое слово this внутри конструктора класса. Когда вызывается конструктор, он:

  • проверьте существование экземпляра и назначьте ему this, если он null
  • вернуть уникальный экземпляр (созданный первым)

Однако есть и недостатки:

Реализация 1: если вы хотите использовать статический метод, вам нужно будет использовать свойство конструктора экспортируемого экземпляра.

Реализация 2: если вы попытаетесь создать экземпляр класса несколько раз, ошибки не возникнет.

Обеспечьте уникальность

За счет использования символа и паттерна SingletonEnforcer из AS3…

… Или предотвращая создание нескольких экземпляров в конструкторе класса:

Опять же, здесь есть некоторые недостатки:

Реализация 3: как и в реализации объекта, вам нужно будет получить .instance через static геттер.

Реализация 4: геттеры / сеттеры недоступны напрямую, так как экземпляр не создается. Вы должны полагаться на статические методы и свойства.

Заключение

Эта статья является лишь результатом небольшого исследования синглтонов в ES6 и, вероятно, не содержит некоторых подробных тестов (не стесняйтесь исправлять, если что-то не так). У каждого решения есть свои преимущества и недостатки, но, в конце концов, выбор того, что вам нужно, - это, вероятно, вопрос вкуса / стиля.

PS: некоторые @ реализации декораторов уже доступны.