Паттерн Одиночка (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