Javascript. Singleton pattern

Паттерн Одиночка (Singleton) гарантирует, что класс имеет только один экземпляр, и предоставляет глобальную точку доступа к этому экземпляру. Данный паттерн определяет альтернативный способ создания объектов - в данном случае уникальных объектов, то есть гарантируется существование в приложении не более одного экземпляра данного класса. Данный паттерн относится к порождающим шаблонам.


Самый простой способ создать такой уникальный объект с глобальной точкой доступа на javascript - создать объект с помощью литералов.

var unique = (function (global) {

        // create global unique singleton object
return global.unique = {};

})(window);

Вот иная реализация (согласно вышеприведенной диаграмме класса Sigleton):

var Singleton = (function () {

// static variable
var uniqueInstance = null;

function Singleton() {
throw new Error("Forbidden to instantiate the Singleton class. Use Singleton.getInstance method");
}

// private constructor
function ctor() {

var id = id || 0;

this.getId = function () {};

this.setId = function (_id) {
id = _id || id;
};
}

// for checking by instanceof Singleton 
ctor.prototype = Singleton.prototype;

Singleton.getInstance = function () {
if (uniqueInstance === null) {
uniqueInstance = new ctor();
}
return uniqueInstance;
};

return Singleton;
})();

// var object1 = new Singleton(); // Forbidden to instantiate the Singleton class. Use Singleton.getInstance method

var object1 = Singleton.getInstance();
var object2 = Singleton.getInstance();

console.log(object1 instanceof Singleton); // true
console.log(object1 === object2); // true

Или вот еще один пример реализации данного паттерна:

var Module = function () {
    
    if (typeof Module.instance === "object") {
        return Module.instance;
    }
    
    var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
        today = new Date(),
        week = days[today.getDay()],
        day = today.getDate(),
        day = day < 10 ? '0' + day : day,
        month = today.getMonth() + 1,
        month = month < 10 ? '0' + month : month,
        year = today.getFullYear();
        hours = today.getHours(),
        minutes = today.getMinutes(),
        initDate = week + ', ' + day + '.' + month + '.' + year,
        initFullDate = week + ', ' + day + '.' + month + '.' + year + ', ' + hours + ':' + minutes;
        
    this.getInitDate = function () {
        return initDate;
    };
    
    this.getInitFullDate = function () {
        return initFullDate;
    };
    
    Module.instance = this;
    
};

var module1 = new Module();
var module2 = new Module();

console.log(module1 === module2); // true
console.log(module1.getInitFullDate()); // Sun, 18.05.2014, 22:44
console.log(module2.getInitFullDate()); // Sun, 18.05.2014, 22:44

Module.prototype.isInit = true;

console.log(module1.isInit); // true
console.log(module2.isInit); // true