Il modo più semplice / pulito per implementare singleton in JavaScript?

Qual è il modo più semplice / pulito per implementare il modello singleton in JavaScript?

Penso che il modo più semplice sia dichiarare un object letterale semplice:

var myInstance = { method1: function () { // ... }, method2: function () { // ... } }; 

Se vuoi membri privati ​​sulla tua istanza singleton, puoi fare qualcosa di simile a questo:

 var myInstance = (function() { var privateVar = ''; function privateMethod () { // ... } return { // public interface publicMethod1: function () { // all private members are accesible here }, publicMethod2: function () { } }; })(); 

Questo è stato chiamato il modello del modulo , in pratica consente di incapsulare membri privati ​​su un object, sfruttando l’uso delle chiusure .

Penso che l’approccio più pulito sia qualcosa come:

 var SingletonClass = (function(){ function SingletonClass() { //do stuff } var instance; return { getInstance: function(){ if (instance == null) { instance = new SingletonClass(); // Hide the constructor so the returned objected can't be new'd... instance.constructor = null; } return instance; } }; })(); 

Successivamente, puoi invocare la funzione come

 var test = SingletonClass.getInstance(); 

Non sono sicuro di essere d’accordo con il modello del modulo utilizzato come sostituto di un modello singleton. Ho visto spesso singletons usati e abusati in luoghi in cui non sono assolutamente necessari, e sono sicuro che il modello del modulo riempie molte lacune in cui i programmatori utilizzerebbero altrimenti un singleton, tuttavia il pattern del modulo non è un singleton.

modello del modulo:

 var foo = (function () { "use strict"; function aPrivateFunction() {} return { aPublicFunction: function () {...}, ... }; }()); 

Tutto inizializzato nel modello del modulo si verifica quando viene dichiarato Foo . Inoltre, il modello di modulo può essere utilizzato per inizializzare un costruttore, che potrebbe quindi essere istanziato più volte. Mentre il modello di modulo è lo strumento giusto per molti lavori, non è equivalente a un singleton.

modello singleton:

forma breve

 var Foo = function () { "use strict"; if (Foo._instance) { //this allows the constructor to be called multiple times //and refer to the same instance. Another option is to //throw an error. return Foo._instance; } Foo._instance = this; //Foo initialization code }; Foo.getInstance = function () { "use strict"; return Foo._instance || new Foo(); } 

forma lunga, usando il modello del modulo

 var Foo = (function () { "use strict"; var instance; //prevent modification of "instance" variable function Singleton() { if (instance) { return instance; } instance = this; //Singleton initialization code } //instance accessor Singleton.getInstance = function () { return instance || new Singleton(); } return Singleton; }()); 

In entrambe le versioni del pattern Singleton che ho fornito, il costruttore stesso può essere utilizzato come accessor:

 var a, b; a = new Foo(); //constructor initialization happens here b = new Foo(); console.log(a === b); //true 

Se non ti senti a tuo agio nell’usare il costruttore in questo modo, puoi lanciare un errore if (instance) e continuare ad usare il modulo lungo:

 var a, b; a = Foo.getInstance(); //constructor initialization happens here b = Foo.getInstance(); console.log(a === b); //true 

Dovrei anche ricordare che il modello singleton si adatta bene al modello implicito della funzione di costruzione:

 function Foo() { if (Foo._instance) { return Foo._instance; } //if the function wasn't called as a constructor, //call it as a constructor and return the result if (!(this instanceof Foo)) { return new Foo(); } Foo._instance = this; } var f = new Foo(); //calls Foo as a constructor -or- var f = Foo(); //also calls Foo as a constructor 

Esistono più modi per skinare un gatto 🙂 A seconda del tuo gusto o delle tue esigenze specifiche puoi applicare una qualsiasi delle soluzioni proposte. Io personalmente vado per la prima soluzione CMS quando ansible (quando non hai bisogno di privacy). Dal momento che la domanda riguardava la più semplice e la più pulita, questo è il vincitore. O anche:

 var myInstance = {}; // done! 

Questo (citazione dal mio blog) …

 var SingletonClass = new function() { this.myFunction() { //do stuff } this.instance = 1; } 

non ha molto senso (il mio blog non lo fa neanche) perché non ha bisogno di alcun vars privato, quindi è praticamente lo stesso di:

 var SingletonClass = { myFunction: function () { //do stuff }, instance: 1 } 

Mi deprecano la mia risposta, vedi l’altra mia .

Di solito il modello del modulo (vedi la risposta del CMS) che NON è un modello singleton è abbastanza buono. Tuttavia, una delle caratteristiche di Singleton è che la sua inizializzazione è ritardata fino a quando l’object è necessario. Il modello del modulo non ha questa caratteristica.

La mia proposta (CoffeeScript):

 window.singleton = (initializer) -> instance = undefined () -> return instance unless instance is undefined instance = initializer() 

Che è stato compilato in questo modo in JavaScript:

 window.singleton = function(initializer) { var instance; instance = void 0; return function() { if (instance !== void 0) { return instance; } return instance = initializer(); }; }; 

Quindi posso fare quanto segue:

 window.iAmSingleton = singleton(function() { /* This function should create and initialize singleton. */ alert("creating"); return {property1: 'value1', property2: 'value2'}; }); alert(window.iAmSingleton().property2); // "creating" will pop up; then "value2" will pop up alert(window.iAmSingleton().property2); // "value2" will pop up but "creating" will not window.iAmSingleton().property2 = 'new value'; alert(window.iAmSingleton().property2); // "new value" will pop up 

Ho ottenuto questo esempio dai pattern JavaScript per creare applicazioni migliori con i modelli di codifica e progettazione del libro di Stoyan Stefanov nel caso in cui sia necessaria una semplice class di implementazione come l’object singltone, è ansible utilizzare la funzione immediata come segue:

 var ClassName; (function() { var instance; ClassName = function ClassName() { //If private instance variable already initialized return reference if(instance) { return instance; } //If instance does not created save pointer of original reference //to private instance variable. instance = this; //All constructor initialization will be here // ie: this.someProperty = 0; this.someMethod = function() { //Some action here }; }; }()); 

E puoi controllare questo esempio seguendo il caso di test:

 //Extending defined class like Singltone object using new prototype property ClassName.prototype.nothing = true; var obj_1 = new ClassName(); //Extending defined class like Singltone object using new prototype property ClassName.prototype.everything = true; var obj_2 = new ClassName(); //Testing does this two object pointing to same instance console.log(obj_1 === obj_2); //Result is true, it points to same instance object //All prototype properites work //no matter when they were defined console.log(obj_1.nothing && obj_1.everything && obj_2.nothing && obj_2.everything); //Result true //Values of properties which is defined inside of constructor console.log(obj_1.someProperty);// output 0 console.log(obj_2.someProperty);// output 0 //Changing property value obj_1.someProperty = 1; console.log(obj_1.someProperty);// output 1 console.log(obj_2.someProperty);// output 1 console.log(obj_1.constructor === ClassName); //Output true 

Questo approccio passa tutti i casi di test mentre l’implementazione statica privata fallisce quando viene utilizzata l’estensione del prototipo (può essere riparata ma non sarà semplice) e l’implementazione statica pubblica meno consigliabile a causa dell’istanza esposta al pubblico.

jsFiddly demo.

Risposta breve:

Poiché la natura non bloccante di JavaScript, Singletons in JavaScript è davvero brutta in uso. Le variabili globali ti daranno un’istanza anche attraverso l’intera applicazione senza tutte queste callback, il modello del modulo nasconde delicatamente gli interni dietro l’interfaccia. Vedi la risposta @CMS.

Ma, dal momento che volevi un singleton …

 var singleton = function(initializer) { var state = 'initial'; var instance; var queue = []; var instanceReady = function(createdInstance) { state = 'ready'; instance = createdInstance; while (callback = queue.shift()) { callback(instance); } }; return function(callback) { if (state === 'initial') { state = 'waiting'; queue.push(callback); initializer(instanceReady); } else if (state === 'waiting') { queue.push(callback); } else { callback(instance); } }; }; 

Uso:

 var singletonInitializer = function(instanceReady) { var preparedObject = {property: 'value'}; // calling instanceReady notifies singleton that instance is ready to use instanceReady(preparedObject); } var s = singleton(singletonInitializer); // get instance and use it s(function(instance) { instance.doSomething(); }); 

Spiegazione:

Singletons ti dà più di una sola istanza attraverso l’intera applicazione: la loro inizializzazione è ritardata fino al primo utilizzo. Questa è davvero una grande cosa quando si affrontano oggetti la cui inizializzazione è costosa. Costoso di solito significa I / O e in JavaScript I / O significa sempre callback.

Non fidarti delle risposte che ti danno un’interfaccia come instance = singleton.getInstance() , mancano tutte le cose.

Se non accettano il callback da eseguire quando l’istanza è pronta, non funzioneranno quando l’inizializzatore esegue I / O.

Sì, i callback sembrano sempre più brutti della funzione call che restituisce immediatamente l’istanza dell’object. Ma ancora: quando fai I / O, i callback sono obbligatori. Se non si desidera eseguire alcun I / O, l’istanziazione è abbastanza economica da farlo all’avvio del programma.

Esempio 1, inizializzatore economico:

 var simpleInitializer = function(instanceReady) { console.log("Initializer started"); instanceReady({property: "initial value"}); } var simple = singleton(simpleInitializer); console.log("Tests started. Singleton instance should not be initalized yet."); simple(function(inst) { console.log("Access 1"); console.log("Current property value: " + inst.property); console.log("Let's reassign this property"); inst.property = "new value"; }); simple(function(inst) { console.log("Access 2"); console.log("Current property value: " + inst.property); }); 

Esempio 2, inizializzazione con I / O:

In questo esempio setTimeout falsifica alcune costose operazioni di I / O. Questo illustra perché i singleton in JavaScript hanno davvero bisogno di callback.

 var heavyInitializer = function(instanceReady) { console.log("Initializer started"); var onTimeout = function() { console.log("Initializer did his heavy work"); instanceReady({property: "initial value"}); }; setTimeout(onTimeout, 500); }; var heavy = singleton(heavyInitializer); console.log("In this example we will be trying"); console.log("to access singleton twice before it finishes initialization."); heavy(function(inst) { console.log("Access 1"); console.log("Current property value: " + inst.property); console.log("Let's reassign this property"); inst.property = "new value"; }); heavy(function(inst) { console.log("Access 2. You can see callbacks order is preserved."); console.log("Current property value: " + inst.property); }); console.log("We made it to the end of the file. Instance is not ready yet."); 

Penso di aver trovato il modo più semplice per programmare in JavaScript, ma avrai bisogno di un po ‘di immaginazione. Ho avuto questa idea da una tecnica di lavoro nel libro “javascript the good parts”.

Invece di usare la nuova parola chiave, potresti creare una class come questa:

 function Class() { var obj = {}; // Could also be used for inheritence if you don't start with an empty object. var privateVar; obj.publicVar; obj.publicMethod= publicMethod; function publicMethod(){} function privateMethod(){} return obj; } 

È ansible creare un’istanza dell’object sopra dicendo:

 var objInst = Class(); // !!! NO NEW KEYWORD 

Ora con questo metodo di lavoro in mente è ansible creare un singleton come questo:

 ClassSingleton = function() { var instance= null; function Class() // This is the class like the above one { var obj = {}; return obj; } function getInstance() { if( !instance ) instance = Class(); // Again no new keyword; return instance; } return { getInstance : getInstance }; }(); 

Ora puoi ottenere la tua istanza chiamando

 var obj = ClassSingleton.getInstance(); 

Penso che questo sia il modo più accurato in quanto la “Classe” completa non è nemmeno accessibile.

Non sono sicuro del motivo per cui nessuno l’ha inventato, ma puoi semplicemente fare:

 var singleton = new (function() { var bar = 123 this.foo = function() { // whatever } })() 

La risposta più chiara dovrebbe essere questa del libro Learning JavaScript Design Patterns di Addy Osmani.

 var mySingleton = (function () { // Instance stores a reference to the Singleton var instance; function init() { // Singleton // Private methods and variables function privateMethod(){ console.log( "I am private" ); } var privateVariable = "Im also private"; var privateRandomNumber = Math.random(); return { // Public methods and variables publicMethod: function () { console.log( "The public can see me!" ); }, publicProperty: "I am also public", getRandomNumber: function() { return privateRandomNumber; } }; }; return { // Get the Singleton instance if one exists // or create one if it doesn't getInstance: function () { if ( !instance ) { instance = init(); } return instance; } }; })(); 

@CMS e @zzzzBov hanno entrambi dato risposte meravigliose, ma solo per aggiungere la mia interpretazione basata sul mio spostamento nello sviluppo di node.js pesante da PHP / Zend Framework in cui i pattern singleton erano comuni.

Il seguente codice di commento documentato si basa sui seguenti requisiti:

  • una e una sola istanza dell’object funzione può essere istanziata
  • l’istanza non è pubblicamente disponibile e può essere accessibile solo attraverso un metodo pubblico
  • il costruttore non è pubblicamente disponibile e può essere istanziato solo se non è già disponibile un’istanza
  • la dichiarazione del costruttore deve consentire la modifica della sua catena di prototipi. Ciò consentirà al costruttore di ereditare da altri prototipi e offrire metodi “pubblici” per l’istanza

Il mio codice è molto simile a @ zzzzBov eccetto che ho aggiunto una catena prototipo al costruttore e più commenti che dovrebbero aiutare chi viene da PHP o un linguaggio simile a tradurre la tradizionale OOP in natura prototipica di Javascripts. Potrebbe non essere il “più semplice”, ma credo che sia il più appropriato.

 // declare 'Singleton' as the returned value of a self-executing anonymous function var Singleton = (function () { "use strict"; // 'instance' and 'constructor' should not be availble in a "public" scope // here they are "private", thus available only within // the scope of the self-executing anonymous function var _instance=null; var _constructor = function (name) { this.name = name || 'default'; } // prototypes will be "public" methods available from the instance _constructor.prototype.getName = function () { return this.name; } // using the module pattern, return a static object // which essentially is a list of "public static" methods return { // because getInstance is defined within the same scope // it can access the "private" 'instance' and 'constructor' vars getInstance:function (name) { if (!_instance) { console.log('creating'); // this should only happen once _instance = new _constructor(name); } console.log('returning'); return _instance; } } })(); // self execute // ensure 'instance' and 'constructor' are unavailable // outside the scope in which they were defined // thus making them "private" and not "public" console.log(typeof _instance); // undefined console.log(typeof _constructor); // undefined // assign instance to two different variables var a = Singleton.getInstance('first'); var b = Singleton.getInstance('second'); // passing a name here does nothing because the single instance was already instantiated // ensure 'a' and 'b' are truly equal console.log(a === b); // true console.log(a.getName()); // "first" console.log(b.getName()); // also returns "first" because it's the same instance as 'a' 

Si noti che, tecnicamente, la funzione anonima autoeseguita è a sua volta un Singleton come dimostrato benissimo nel codice fornito da @CMS. L’unico problema è che non è ansible modificare la catena del prototipo del costruttore quando il costruttore stesso è anonimo.

Tieni presente che in Javascript, i concetti di “pubblico” e “privato” non si applicano come fanno in PHP o Java. Ma abbiamo raggiunto lo stesso effetto sfruttando le regole di Javascript della disponibilità degli scope funzionali.

In es6 :

 class Singleton { constructor () { if (!Singleton.instance) { Singleton.instance = this } // Initialize object return Singleton.instance } // Properties & Methods } const instance = new Singleton() Object.freeze(instance) export default instance 

posso mettere le mie 5 monete. Ho una funzione di costruzione, es.

 var A = function(arg1){ this.arg1 = arg1 }; 

Quello che devo fare è che ogni object creato da questo CF sarà lo stesso.

 var X = function(){ var instance = {}; return function(){ return instance; } }(); 

test

 var x1 = new X(); var x2 = new X(); console.log(x1 === x2) 

Il seguente funziona nel nodo v6

 class Foo { constructor(msg) { if (Foo.singleton) { return Foo.singleton; } this.msg = msg; Foo.singleton = this; return Foo.singleton; } } 

Testiamo:

 const f = new Foo('blah'); const d = new Foo('nope'); console.log(f); // => Foo { msg: 'blah' } console.log(d); // => Foo { msg: 'blah' } 

Ho trovato che il seguente è il modello Singleton più semplice, perché l’utilizzo del nuovo operatore lo rende immediatamente disponibile all’interno della funzione, eliminando la necessità di restituire un object letterale:

 var singleton = new (function () { var private = "A private value"; this.printSomething = function() { console.log(private); } })(); singleton.printSomething(); 

Avevo bisogno di diversi singleton con:

  • inizializzazione pigra
  • parametri iniziali

e così è stato quello che mi è venuto in mente:

 createSingleton ('a', 'add', [1, 2]); console.log(a); function createSingleton (name, construct, args) { window[name] = {}; window[construct].apply(window[name], args); window[construct] = null; } function add (a, b) { this.a = a; this.b = b; this.sum = a + b; } 
  • args deve essere Array perché funzioni così se hai variabili vuote, passa semplicemente []

  • Ho usato l’object window nella funzione ma avrei potuto passare in un parametro per creare il mio scope

  • i parametri name e construct sono solo String per window [], ma con alcuni semplici controlli di tipo sono anche possibili window.name e window.construct.

Cosa c’è di sbagliato in questo?

 function Klass() { var instance = this; Klass = function () { return instance; } } 

Che ne dici di questo, assicurati solo che la class non possa essere di nuovo nuova.

Con questo, puoi usare l’ instanceof op, inoltre, puoi usare la catena del prototipo per ereditare la class, è una class regolare, ma non può essere nuova, se vuoi ottenere l’istanza usa solo getInstance

 function CA() { if(CA.instance) { throw new Error('can not new this class'); }else{ CA.instance = this; } } /** * @protected * @static * @type {CA} */ CA.instance = null; /** @static */ CA.getInstance = function() { return CA.instance; } CA.prototype = /** @lends CA#*/ { func: function(){console.log('the func');} } // initilize the instance new CA(); // test here var c = CA.getInstance() c.func(); console.assert(c instanceof CA) // this will failed var b = new CA(); 

Se non si desidera esporre il membro instance , è sufficiente inserirlo in una chiusura.

di seguito è il frammento dalla mia passeggiata attraverso per implementare un modello singleton. Mi è venuto in mente durante un colloquio e ho sentito che dovevo catturarlo da qualche parte.

 /************************************************* * SINGLETON PATTERN IMPLEMENTATION * *************************************************/ //since there are no classs in javascript, every object is technically a singleton //if you don't inherit from it or copy from it. var single = {}; //Singleton Implementations //Declaring as a Global Object...you are being judged! var Logger = function() { //global_log is/will be defined in GLOBAL scope here if(typeof global_log === 'undefined'){ global_log = this; } return global_log; }; //the below 'fix' solves the GLOABL variable problem but //the log_instance is publicly available and thus can be //tampered with. function Logger() { if(typeof Logger.log_instance === 'undefined'){ Logger.log_instance = this; } return Logger.log_instance; }; //the correct way to do it to give it a closure! function logFactory() { var log_instance; //private instance var _initLog = function() { //private init method log_instance = 'initialized'; console.log("logger initialized!") } return { getLog : function(){ //the 'privileged' method if(typeof log_instance === 'undefined'){ _initLog(); } return log_instance; } }; } /***** TEST CODE ************************************************ //using the Logger singleton var logger = logFactory();//did i just gave LogFactory a closure? //create an instance of the logger var a = logger.getLog(); //do some work //get another instance of the logger var b = logger.getLog(); //check if the two logger instances are same? console.log(a === b); //true *******************************************************************/ 

lo stesso si può trovare sulla mia pagina di Gist

 function Unicode() { var i = 0, unicode = {}, zero_padding = "0000", max = 9999; //Loop through code points while (i < max) { //Convert decimal to hex value, find the character, then pad zeroes to the codepoint unicode[String.fromCharCode(parseInt(i, 16))] = ("u" + zero_padding + i).substr(-4); i = i + 1; } //Replace this function with the resulting lookup table Unicode = unicode; } //Usage Unicode(); //Lookup Unicode["%"]; //returns 0025 

Non è anche un singleton?

 function Singleton() { var i = 0; var self = this; this.doStuff = function () { i = i + 1; console.log( 'do stuff',i ); }; Singleton = function () { return self }; return this; } s = Singleton(); s.doStuff(); 

Puoi farlo con decoratori come in questo esempio qui sotto per TypeScript:

 class YourClass { @Singleton static singleton() {} } function Singleton(target, name, descriptor) { var instance; descriptor.value = () => { if(!instance) instance = new target; return instance; }; } 

Quindi usi il tuo singleton in questo modo:

 var myInstance = YourClass.singleton(); 

Al momento della stesura, i decoratori non sono prontamente disponibili nei motori JavaScript. Dovresti assicurarti che il tuo runtime JavaScript abbia effettivamente abilitato i decoratori o usi compilatori come Babel e TypeScript.

Si noti inoltre che l’istanza singleton viene creata “lazy”, ovvero viene creata solo quando la si usa per la prima volta.

Schema del modulo: in “stile più leggibile”. Puoi vedere facilmente quali metodi sono pubblici e quali sono privati

 var module = (function(_name){ /*Local Methods & Values*/ var _local = { name : _name, flags : { init : false } } function init(){ _local.flags.init = true; } function imaprivatemethod(){ alert("hi im a private method"); } /*Public Methods & variables*/ var $r = {}; //this object will hold all public methods. $r.methdo1 = function(){ console.log("method1 call it"); } $r.method2 = function(){ imaprivatemethod(); //calling private method } $r.init = function(){ inti(); //making init public in case you want to init manually and not automatically } init(); //automatically calling init method return $r; //returning all publics methods })("module"); 

ora puoi usare metodi pubblici come

module.method2 (); // -> Sto chiamando un metodo privato su un avviso di metodo pubblico (“hi im a private method”)

http://jsfiddle.net/ncubica/xMwS9/

Singleton:

Assicurati che una class abbia una sola istanza e fornisca un accesso globale ad essa.

Il Pattern Singleton limita il numero di istanze di un particolare object a una sola. Questa singola istanza è chiamata singleton.

  • definisce getInstance () che restituisce l’istanza univoca.
  • responsabile della creazione e della gestione dell’object istanza.

L’object Singleton è implementato come funzione anonima immediata. La funzione viene eseguita immediatamente avvolgendola tra parentesi seguita da due parentesi aggiuntive. Si chiama anonimo perché non ha un nome.

Programma di esempio,

 var Singleton = (function () { var instance; function createInstance() { var object = new Object("I am the instance"); return object; } return { getInstance: function () { if (!instance) { instance = createInstance(); } return instance; } }; })(); function run() { var instance1 = Singleton.getInstance(); var instance2 = Singleton.getInstance(); alert("Same instance? " + (instance1 === instance2)); } run() 

Ecco il semplice esempio per spiegare il pattern singleton nello script java.

  var Singleton=(function(){ var instance; var init=function(){ return { display:function(){ alert("This is a Singleton patern demo"); } }; }; return { getInstance:function(){ if(!instance){ alert("Singleton check"); instance=init(); } return instance; } }; })(); // In this call first display alert("Singleton check") // and then alert("This is a Singleton patern demo"); // It means one object is created var inst=Singleton.getInstance(); inst.display(); // In this call only display alert("This is a Singleton patern demo") // it means second time new object is not created, // it uses the already created object var inst1=Singleton.getInstance(); inst1.display(); 

Mi piace usare una combinazione di Singleton con il modello del modulo, ramificazioni di init-time con un controllo Global NS, avvolto in una chiusura. Nel caso in cui l’ambiente non cambierà dopo l’inizializzazione del singleton; l’uso di un object letterale immediatamente invocato per restituire un modulo pieno di utilità che persisterà per una certa durata dovrebbe andare bene. Non sto passando alcuna dipendenza, solo invocando i singleton all’interno del loro piccolo mondo – l’unico objective è: creare un modulo di utilità per l’associazione / disassociazione di eventi (le modifiche all’orientamento / orientamento del dispositivo potrebbero anche funzionare in questo caso).

 window.onload = ( function( _w ) { console.log.apply( console, ['it', 'is', 'on'] ); ( { globalNS : function() { var nameSpaces = ["utils", "eventUtils"], nsLength = nameSpaces.length, possibleNS = null; outerLoop: for ( var i = 0; i < nsLength; i++ ) { if ( !window[nameSpaces[i]] ) { window[nameSpaces[i]] = this.utils; break outerLoop; }; }; }, utils : { addListener : null, removeListener : null }, listenerTypes : { addEvent : function( el, type, fn ) { el.addEventListener( type, fn, false ); }, removeEvent : function( el, type, fn ) { el.removeEventListener( type, fn, false ); }, attachEvent : function( el, type, fn ) { el.attachEvent( 'on'+type, fn ); }, detatchEvent : function( el, type, fn ) { el.detachEvent( 'on'+type, fn ); } }, buildUtils : function() { if ( typeof window.addEventListener === 'function' ) { this.utils.addListener = this.listenerTypes.addEvent; this.utils.removeListener = this.listenerTypes.removeEvent; } else { this.utils.attachEvent = this.listenerTypes.attachEvent; this.utils.removeListener = this.listenerTypes.detatchEvent; }; this.globalNS(); }, init : function() { this.buildUtils(); } } ).init(); }( window ) ); 

You did not say “in the browser”. Otherwise, you can use NodeJS modules . These are the same for each require call . Basic example:

The contents of foo.js:

 const circle = require('./circle.js'); console.log( `The area of a circle of radius 4 is ${circle.area(4)}`); 

The contents of circle.js:

 const PI = Math.PI; exports.area = (r) => PI * r * r; exports.circumference = (r) => 2 * PI * r; 

Note that you cannot access circle.PI , as it is not exported.

While this does not work in the browser, it is simple and clean.

Main key is to Undertand Closure importance behind this.So property even inside the inner function will be private with the help of closure.

var Singleton = function () { var instance;

  function init() { function privateMethod() { console.log("private via closure"); } var privateVariable = "Private Property"; var privateRandomNumber = Math.random();// this also private return { getRandomNumber: function () { // access via getter in init call return privateRandomNumber; } }; }; return { getInstance: function () { if (!instance) { instance = init(); } return instance; } }; 

};

Singleton in javascript is achieved using Module pattern and closures. Below is the code which is pretty much self-explanatory –

 // singleton example. var singleton = (function() { var instance; function init() { var privateVar1 = "this is a private variable"; var privateVar2 = "another var"; function pubMethod() { //accessing private variables from inside. console.log(this.privateVar1); console.log(this.privateVar2); console.log("inside of a public method"); }; } function getInstance() { if (!instance) { instance = init(); } return instance; }; return { getInstance: getInstance } })(); var obj1 = singleton.getInstance(); var obj2 = singleton.getInstance(); cnosole.log(obj1===obj2); //check for type and value. 

I believe this is the simplest/cleanest and most intuitive way though it requires ES7:

 export default class Singleton { static instance; constructor(){ if(instance){ return instance; } this.state = "duke"; this.instance = this; } } 

The source code is from: adam-bien.com