Вспомогательная функция Javascript для преобразования функции конструктора класса в Singleton

Я кое-что читал о двух способах создания синглтона в 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"

Я просто пытаюсь определить здесь метод «Singleton».

Я видел аналогичный пример, где метод getInstance используется для получения экземпляра, такого как - Singleton.getInstance(Circle) и т. д., но я ищу конкретный вопрос выше, где другой программист привык создавать экземпляр в «новый» способ пытается запустить new Circle(); второй раз где-то в своем коде и получает ошибку.

Создание синглтона таким образом - это одна проблема, но основная проблема заключается в том, чтобы выдать "Ошибку", для которой, насколько я понимаю, конструктор Circle должен быть изменен где-то в функции Singleton, не знаю, как это сделать.

Есть ли какое-нибудь решение?

Заранее спасибо !!


person Anmol Saraf    schedule 05.11.2012    source источник


Ответы (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. Что-либо в любом другом пространстве имен потребует дополнительных манипуляций, чтобы заставить его работать полностью.

person Naftali aka Neal    schedule 05.11.2012
comment
Молниеносно я увидел, как первый фрагмент кода появился через несколько секунд после того, как я опубликовал этот вопрос, а затем вы продолжали добавлять вызов и jsfiddle, что заняло около 2 минут. Точность с такой скоростью просто невероятная. Он охватывает все требования, такие как: я не могу изменить уже написанную функцию Circle, и функция круга должна быть независимой от функции Singleton, а функция Singleton изменяет функцию Circle. Это решение можно легко применить к любому предварительно написанному коду. Я ждал, что другие люди ответят на этот вопрос, но на самом деле у меня было очень мало надежды получить лучшие ответы. - person Anmol Saraf; 06.11.2012
comment
Настоящий гениальный ответ за считанные секунды :) Большое спасибо - person Anmol Saraf; 06.11.2012
comment
@AnmolSaraf Нет проблем ^_^ Рад помочь! - person Naftali aka Neal; 06.11.2012

Попробуй это:

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 () { //...
person metadings    schedule 05.11.2012

Конечно, вы также можете создать один объект экземпляра с возможностью использования замыканий с чем-то вроде:

var singlecircle = (new function(name) {
         this.name = name || "Default circle";}('squared')
    );
singlecircle.name; //=> 'squared'
person KooiInc    schedule 06.11.2012