Полезная функция 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'
Другие вопросы по тегам