Полезная функция Javascript для преобразования класса - "функции конструктора" в синглтон
У меня есть некоторое чтение о двух способах создания синглтона в javascript - обычном объектном литеральном способе и другом с техникой замыкания, если мы хотим использовать закрытые переменные.
Я ищу, чтобы создать функцию полезности, например
Singleton(classname);
Независимо от класса - "конструктор функции", который я передаю здесь в качестве аргумента, метод Singleton преобразует этот класс в объект Singleton, ПЛЮС после вызова new Classname()
если кто-то снова запускает новое имя класса (), он / она получает некоторые new Error ( "Already instantiated once, this is Singleton" );
Вариант использования, как показано ниже -
function Circle() {this.name = "Circle";}
SingleTon(Circle);
var circle1 = new Circle(); // returns the circle instance
var circle2 = new Circle(); // throws Error "Already instantiated once, this is Singleton"
Я просто пытаюсь определить метод "Синглтон" здесь.
Я видел похожий пример, где метод getInstance используется для получения экземпляра, например - Singleton.getInstance (Circle) и т. Д., Но я ищу конкретный вопрос выше, где другой программист, привычный к созданию экземпляра "новым" способом, пытается Пожар new Circle();
второй раз где-то в своем коде и получает ошибку.
Создание синглтона таким способом является одной из проблем, но главная проблема заключается в выдаче "ошибки", из-за которой, насколько я понимаю, конструктор Circle нужно где-то изменить в функции Singleton, не зная, как этого добиться.
Есть ли решение?
Заранее спасибо!!
3 ответа
function Singleton(param){
var count = 0, old = window[param];
window[param] = function(){
if(++count <= 1) return old;
else alert('NO WAY!');
}
}
Вы бы назвали это как:
Singleton('Circle');
Демо: http://jsfiddle.net/maniator/7ZFmE/
Помните, что это работает только если Circle
или любой другой класс функции находится в глобальном window
Пространство имен. Все, что находится в любом другом пространстве имен, потребует дополнительных манипуляций, чтобы оно работало полностью.
Попробуй это:
Circle = function () {
if (!(this instanceof Circle)) {
// called as function
return Circle.singleton || (Circle.singleton = new Circle());
}
// called as constructor
this.name = "the circle";
};
Теперь без нового оператора вы получаете синглтон или новый, используя
var mycircle = Circle();
Осторожно, я использую глобальное имя для примера, вы также можете сделать
var Circle = window.Circle = function () { //...
Конечно, вы можете также создать один экземпляр Object с возможностью использования замыканий с чем-то вроде:
var singlecircle = (new function(name) {
this.name = name || "Default circle";}('squared')
);
singlecircle.name; //=> 'squared'