Какой самый простой / чистый способ реализовать шаблон синглтона в JavaScript?
javascript
function
design-patterns
singleton
Якуб Арнольд
источник
источник
Ответы:
Я думаю, что самый простой способ - объявить простой объектный литерал:
Если вы хотите, чтобы в вашем экземпляре синглтона были приватные участники, вы можете сделать что-то вроде этого:
Это было названо в шаблон модуля , это в принципе позволяет инкапсулировать частных пользователей на объекте, воспользовавшись использованием затворов .
ОБНОВЛЕНИЕ: Я хотел бы добавить, что если вы хотите предотвратить модификацию одноэлементного объекта, вы можете заморозить его , используя
Object.freeze
метод ES5 .Это сделает объект неизменным, предотвращая любые изменения его структуры и значений.
Кроме того, я хотел бы отметить, что если вы используете ES6, вы можете очень легко представлять одиночный файл с помощью модулей ES , и вы даже можете хранить приватное состояние , объявив переменные в области видимости модуля :
Затем вы можете просто импортировать объект singleton, чтобы использовать его:
источник
publicMethod1
позвонитьpublicMethod2
?getInstance
метод и закрытый конструктор, но IMO, это самый «простой» способ создания одноэлементного объекта. в Javascript, и в конце он встречает ту же цель - единственный объект, который вы не можете инициализировать снова (нет конструктора, это просто объект) -. О коде вы связаны, у него есть какие - то проблемы, поменять местамиa
иb
объявления переменных и тестa === window
. Приветствия.Я думаю, что самый чистый подход - это что-то вроде:
После этого вы можете вызвать функцию как
источник
delete instance.constructor
:x = SingletonClass.getInstance();delete x.constructor;new x.constructor;
Я не уверен, что согласен с шаблоном модуля, который используется в качестве замены одноэлементного шаблона. Я часто видел синглтоны, которые использовались и злоупотребляли в местах, где они совершенно не нужны, и я уверен, что шаблон модуля заполняет много пробелов, где программисты иначе использовали бы синглтон, однако шаблон модуля не является синглтоном.
шаблон модуля:
Все, что инициализировано в шаблоне модуля, происходит при
Foo
объявлении. Кроме того, шаблон модуля может использоваться для инициализации конструктора, который затем может быть создан несколько раз. Хотя шаблон модуля является подходящим инструментом для многих заданий, он не эквивалентен одиночному.синглтон
короткая форма полная форма, с использованием шаблона модуляВ обеих версиях шаблона Singleton, который я предоставил, сам конструктор может использоваться как средство доступа:
Если вам неудобно использовать конструктор таким образом, вы можете выдать ошибку в
if (instance)
операторе и придерживаться использования длинной формы:Следует также отметить, что шаблон синглтона хорошо согласуется с шаблоном функции неявного конструктора:
источник
var singleton = {}
не подходит под это определение.var singleton = {}
Вот как вы реализуете синглтон в Javascript .В
es6
:источник
instance
поле. Поскольку он в данный момент (instance
установленthis
), этот класс может иметь и другие поля, и заморозка не имеет смысла.Следующие работы в узле v6
Мы тестируем:
источник
В ES6 правильный способ сделать это:
Или, если вы не хотите выдавать ошибку при создании второго экземпляра, вы можете просто вернуть последний экземпляр, например так:
источник
instance
и_instance
. Это просто соглашение об именах в языках программирования, в котором мы называем частные переменные с добавлением подчеркивания. Я подозреваю, что причина вашего кода не работает в том, что вы используетеthis.instance
вместоMyClass.instance
Существует более одного способа кожи кошки :) В зависимости от вашего вкуса или конкретной потребности вы можете применить любое из предложенных решений. Лично я по возможности выбираю первое решение CMS (когда вам не нужна конфиденциальность). Поскольку вопрос был о самом простом и чистом, это победитель. Или даже:
Это (цитата из моего блога) ...
не имеет особого смысла (пример моего блога тоже не имеет), потому что ему не нужны частные переменные, так что это почти так же, как:
источник
this.f(){}
Я не одобряю мой ответ, см. Мой другой .
Обычно шаблон модуля (см. Ответ CMS), который НЕ является одноэлементным, достаточно хорош. Однако одной из особенностей singleton является то, что его инициализация задерживается до тех пор, пока объект не понадобится. В шаблоне модуля отсутствует эта функция.
Мое предложение (CoffeeScript):
Который скомпилирован в JavaScript:
Тогда я могу сделать следующее:
источник
Короткий ответ:
Поскольку неблокирующая природа JavaScript, Singletons в JavaScript действительно ужасны в использовании. Глобальные переменные также дадут вам один экземпляр для всего приложения без всех этих обратных вызовов, шаблон модуля мягко скрывает внутренние компоненты за интерфейсом. Смотрите ответ @CMS.
Но, так как вы хотели синглтон ...
Использование:
Объяснение:
Синглтоны дают вам более одного экземпляра для всего приложения: их инициализация задерживается до первого использования. Это действительно большая вещь, когда вы имеете дело с объектами, инициализация которых стоит дорого. Дорогой обычно означает ввод / вывод, а в JavaScript ввод / вывод всегда означает обратный вызов.
Не верьте ответам, которые дают вам интерфейс, как
instance = singleton.getInstance()
они все упускают суть.Если они не принимают обратный вызов для запуска, когда экземпляр готов, то они не будут работать, когда инициализатор выполняет ввод-вывод.
Да, обратные вызовы всегда выглядят хуже, чем вызов функции, которая немедленно возвращает экземпляр объекта. Но опять же: когда вы делаете ввод / вывод, обратные вызовы обязательны. Если вы не хотите выполнять какие-либо операции ввода-вывода, то создание экземпляра достаточно дешево, чтобы сделать это при запуске программы.
Пример 1, дешевый инициализатор:
Пример 2, инициализация с I / O:
В этом примере
setTimeout
подделка некоторых дорогостоящих операций ввода-вывода. Это показывает, почему синглтонам в JavaScript действительно нужны обратные вызовы.источник
Я получил этот пример из JavaScript Patterns. Создайте лучшие приложения с помощью шаблонов кодирования и дизайна. По книге Стояна Стефанова, если вам нужен какой-то простой класс реализации, такой как объект singltone, вы можете использовать непосредственную функцию следующим образом:
И вы можете проверить этот пример следующим тестом:
Этот подход пропускает все тестовые случаи, в то время как частная статическая реализация завершится неудачно, когда используется расширение прототипа (оно может быть исправлено, но не будет простым), и публичная статическая реализация менее желательна из-за того, что экземпляр открыт для публики.
jsFiddly демо.
источник
Я думаю, что нашел самый чистый способ программирования на JavaScript, но вам нужно немного воображения. Я получил эту идею из техники работы в книге "Javascript хорошие части".
Вместо использования нового ключевого слова вы можете создать класс, подобный этому:
Вы можете создать экземпляр вышеупомянутого объекта, сказав:
Теперь, имея в виду этот метод работы, вы можете создать синглтон, подобный этому:
Теперь вы можете получить свой экземпляр, позвонив
Я думаю, что это самый удачный способ, так как полный «Класс» даже недоступен.
источник
@CMS и @zzzzBov оба дали замечательные ответы, но просто добавили мою собственную интерпретацию, основанную на том, что я перешел в разработку heavy node.js из PHP / Zend Framework, где синглтон-шаблоны были распространены.
Следующий документированный код основан на следующих требованиях:
Мой код очень похож на код @ zzzzBov, за исключением того, что я добавил цепочку прототипов в конструктор и добавил больше комментариев, которые должны помочь тем, кто прибывает из PHP или аналогичного языка, переводить традиционный ООП в прототип Javascripts. Это может быть не самое простое, но я считаю, что это самое правильное.
Обратите внимание, что технически самоисполняющаяся анонимная функция сама по себе является синглтоном, что хорошо продемонстрировано в коде, предоставленном @CMS. Единственный улов здесь заключается в том, что невозможно изменить цепочку прототипов конструктора, когда сам конструктор является анонимным.
Помните, что в Javascript понятия «открытый» и «закрытый» не применяются, как в PHP или Java. Но мы достигли того же эффекта, используя правила доступности функциональных возможностей Javascript.
источник
var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');
Не знаю, почему никто не поднял это, но вы могли бы просто сделать:
источник
Самый ясный ответ должен быть этот из книги «Изучение шаблонов дизайна JavaScript» Эдди Османи.
источник
Я считаю, что это самый простой / чистый и интуитивно понятный способ, хотя он требует ES7:
Исходный код от: adam-bien.com
источник
new Singleton()
Что с этим не так?
источник
Test = Klass; t1 = new Test(); t2 = new Test();
- нет возможности переименовать класс или выбрать другое пространство имен.Могу ли я положить свои 5 монет. У меня есть функция конструктора, напр.
Что мне нужно сделать, так это то, что все объекты, созданные этим CF, будут одинаковыми.
тест
источник
Я обнаружил, что следующее - это самый простой шаблон Singleton, потому что использование оператора new делает его сразу доступным внутри функции, устраняя необходимость возвращать литерал объекта:
источник
Вот простой пример для объяснения синглтон-паттерна в javascript.
источник
Мне нужно было несколько синглетонов с:
и вот что я придумал:
args должен быть Array, чтобы это работало, поэтому если у вас есть пустые переменные, просто передайте []
Я использовал оконный объект в функции, но мог бы передать параметр, чтобы создать собственную область видимости.
Параметры name и construct являются только String для работы window [], но с некоторой простой проверкой типов также возможны window.name и window.construct.
источник
Как насчет этого, просто застраховать, класс не может снова новый.
Таким образом, вы можете использовать
instanceof
опцию, также вы можете использовать цепочку прототипов для наследования класса, это обычный класс, но вы не можете его создать, если вы хотите получить экземпляр, просто используйтеgetInstance
Если вы не хотите выставлять
instance
участника, просто поместите его в закрытие.источник
Ниже приведен фрагмент из моей прогулки по реализации шаблона синглтона. Это произошло со мной во время собеседования, и я почувствовал, что должен это где-то запечатлеть.
то же самое можно найти на моей GIST странице
источник
источник
Разве это не синглтон тоже?
источник
Вы можете сделать это с помощью декораторов, как в следующем примере для TypeScript:
Затем вы используете свой синглтон так:
На момент написания статьи декораторы не всегда были доступны в движках JavaScript. Вам нужно убедиться, что в вашей среде выполнения JavaScript действительно включены декораторы, или использовать компиляторы, такие как Babel и TypeScript.
Также обратите внимание, что экземпляр singleton создается «ленивым», т. Е. Создается только при первом его использовании.
источник
Шаблон модуля: в «более читаемом стиле». Вы можете легко увидеть, какие методы являются публичными, а какие приватными
Теперь вы можете использовать публичные методы, такие как
module.method2 (); // -> я вызываю приватный метод через оповещение о публичном методе («привет, я приватный метод»)
http://jsfiddle.net/ncubica/xMwS9/
источник
Синглтон:
Убедитесь, что у класса есть только один экземпляр, и предоставьте ему глобальную точку доступа.
Шаблон Singleton ограничивает количество экземпляров определенного объекта только одним. Этот единственный экземпляр называется синглтоном.
Объект Singleton реализован как непосредственная анонимная функция. Функция выполняется немедленно, заключив ее в квадратные скобки, за которыми следуют две дополнительные скобки. Он называется анонимным, потому что у него нет имени.
Образец программы,
источник
Simplest / Cleanest для меня означает также простое понимание и никаких наворотов, о чем много говорится в Java-версии обсуждения:
Каков эффективный способ реализации одноэлементного шаблона в Java?
Ответ, который подошел бы самым простым / чистым лучше всего с моей точки зрения:
https://stackoverflow.com/a/70824/1497139
И это может быть только частично переведено на JavaScript. Некоторые из различий в Javascript:
Но учитывая последний синтаксис ECMA, можно приблизиться к:
Шаблон Singleton как пример класса JavaScript
Пример использования
Пример результата
источник
Если вы в классах:
Тест:
источник
Если вы хотите использовать классы:
Выход для вышеупомянутого будет:
Другой способ написания синглтона с использованием функции
Выход для вышеупомянутого будет:
источник