Duplicate possible:
Moyen le plus simple/le plus propre d'implémenter singleton en JavaScript?
J'utilise ce modèle pour des singletons, dans l'exemple le singleton est PlanetEarth:
var NAMESPACE = function () {
var privateFunction1 = function () {
privateFunction2();
};
var privateFunction2 = function () {
alert('I\'m private!');
};
var Constructors = {};
Constructors.PlanetEarth = function () {
privateFunction1();
privateFunction2();
};
Constructors.PlanetEarth.prototype = {
someMethod: function () {
if (console && console.log) {
console.log('some method');
}
}
};
Constructors.Person = function (name, address) {
this.name = name;
this.address = address;
};
Constructors.Person.prototype = {
walk: function () {
alert('STOMP!');
}
};
return {
Person: Constructors.Person, // there can be many
PlanetEarth: new Constructors.PlanetEarth() // there can only be one!
};
}();
Étant donné que le constructeur de de PlanetEarth reste privé, il ne peut en exister qu'un.
Maintenant, quelque chose me dit que cette technique auto-cuisinée n'est pas ce que l'on peut faire de mieux, principalement parce que je n'ai pas d'éducation académique et que j'ai tendance à résoudre les problèmes de manière stupide. Que proposeriez-vous comme meilleur ma méthode alternative, où meilleur est défini comme stylistiquement meilleur et/ou plus puissant ?
(1) UPDATE 2019: Version ES7
class Singleton {
static instance;
constructor() {
if (instance) {
return instance;
}
this.instance = this;
}
foo() {
// ...
}
}
console.log(new Singleton() === new Singleton());
(2) Version ES6
class Singleton {
constructor() {
const instance = this.constructor.instance;
if (instance) {
return instance;
}
this.constructor.instance = this;
}
foo() {
// ...
}
}
console.log(new Singleton() === new Singleton());
Meilleure solution trouvée: http://code.google.com/p/jslibs/wiki/JavascriptTips#Singleton_pattern
function MySingletonClass () {
if (arguments.callee._singletonInstance) {
return arguments.callee._singletonInstance;
}
arguments.callee._singletonInstance = this;
this.Foo = function () {
// ...
};
}
var a = new MySingletonClass();
var b = MySingletonClass();
console.log( a === b ); // prints: true
Pour ceux qui veulent la version stricte:
(function (global) {
"use strict";
var MySingletonClass = function () {
if (MySingletonClass.prototype._singletonInstance) {
return MySingletonClass.prototype._singletonInstance;
}
MySingletonClass.prototype._singletonInstance = this;
this.Foo = function() {
// ...
};
};
var a = new MySingletonClass();
var b = MySingletonClass();
global.result = a === b;
} (window));
console.log(result);
Pourquoi utiliser un constructeur et un prototypage pour un seul objet?
Ce qui précède est équivalent à:
var earth= {
someMethod: function () {
if (console && console.log)
console.log('some method');
}
};
privateFunction1();
privateFunction2();
return {
Person: Constructors.Person,
PlanetEarth: earth
};
Extending le post ci-dessus de Tom, si vous avez besoin d'une déclaration de type de classe et accédez à l'instance de singleton à l'aide d'une variable, le code ci-dessous pourrait vous être utile. J'aime cette notation car le code est peu autoguidé.
function SingletonClass(){
if ( arguments.callee.instance )
return arguments.callee.instance;
arguments.callee.instance = this;
}
SingletonClass.getInstance = function() {
var singletonClass = new SingletonClass();
return singletonClass;
};
Pour accéder au singleton, vous devez
var singleTon = SingletonClass.getInstance();
function SingletonClass()
{
// demo variable
var names = [];
// instance of the singleton
this.singletonInstance = null;
// Get the instance of the SingletonClass
// If there is no instance in this.singletonInstance, instanciate one
var getInstance = function() {
if (!this.singletonInstance) {
// create a instance
this.singletonInstance = createInstance();
}
// return the instance of the singletonClass
return this.singletonInstance;
}
// function for the creation of the SingletonClass class
var createInstance = function() {
// public methodes
return {
add : function(name) {
names.Push(name);
},
names : function() {
return names;
}
}
}
// wen constructed the getInstance is automaticly called and return the SingletonClass instance
return getInstance();
}
var obj1 = new SingletonClass();
obj1.add("Jim");
console.log(obj1.names());
// prints: ["Jim"]
var obj2 = new SingletonClass();
obj2.add("Ralph");
console.log(obj1.names());
// Ralph is added to the singleton instance and there for also acceseble by obj1
// prints: ["Jim", "Ralph"]
console.log(obj2.names());
// prints: ["Jim", "Ralph"]
obj1.add("Bart");
console.log(obj2.names());
// prints: ["Jim", "Ralph", "Bart"]