usar script patrones patron es6 ejercicios diseño cuando javascript function design-patterns singleton

patrones - ¿La forma más simple/limpia de implementar singleton en JavaScript?



singleton java script (30)

Respuesta corta:

Debido a la naturaleza no bloqueante de JavaScript, los Singletons en JavaScript son realmente feos en uso. Las variables globales también le darán una instancia a través de toda la aplicación sin todas estas devoluciones de llamada, el patrón del módulo oculta las partes internas detrás de la interfaz. Ver respuesta @CMS.

Pero, ya que querías 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(); });

Explicación:

Singletons le ofrece más de una instancia a través de toda la aplicación: su inicialización se retrasa hasta el primer uso. Esto es realmente importante cuando se trata de objetos cuya inicialización es costosa. Por lo general, caro significa I / O y en JavaScript I / O siempre significa devoluciones de llamada.

No confíe en las respuestas que le dan una interfaz como instance = singleton.getInstance() , todas faltan el punto.

Si no toman la devolución de llamada para ejecutarse cuando la instancia está lista, entonces no funcionarán cuando el inicializador realice la E / S.

Sí, las devoluciones de llamada siempre parecen más feas que la llamada de función, que devuelve inmediatamente la instancia del objeto. Pero de nuevo: cuando haces E / S, las devoluciones de llamada son obligatorias. Si no desea realizar ninguna E / S, la creación de instancias es lo suficientemente barata para hacerlo al inicio del programa.

Ejemplo 1, inicializador barato:

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); });

Ejemplo 2, inicialización con E / S:

En este ejemplo, setTimeout falsifica algunas operaciones de E / S caras. Esto ilustra por qué los singletons en JavaScript realmente necesitan devoluciones de llamada.

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.");

¿Cuál es la forma más sencilla / limpia de implementar un patrón de singleton en JavaScript?


¿No es esto un singleton también?

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();


¿Puedo poner mis 5 monedas. Tengo una función constructora, ej.

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

Lo que debo hacer es que cada objeto creado por este CF será el mismo.

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

prueba

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


¿Qué pasa con esto?

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


¿Qué tal de esta manera, solo asegúrate de que la clase no puede ser nueva otra vez

Por esto, puede usar la instanceof op, también, puede usar la cadena de prototipo para heredar la clase, es una clase regular, pero no puede ser nueva, si quiere obtener la instancia solo use 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();

Si no desea exponer al miembro de la instance , simplemente póngalo en un cierre.


@CMS y @zzzzBov han dado respuestas maravillosas, pero solo para agregar mi propia interpretación basada en mi traslado al desarrollo de node.js pesado desde PHP / Zend Framework donde los patrones singleton eran comunes.

El siguiente código documentado de comentarios se basa en los siguientes requisitos:

  • una y solo una instancia del objeto de función puede ser instanciada
  • la instancia no está disponible públicamente y solo se puede acceder a ella mediante un método público
  • el constructor no está disponible públicamente y solo se puede crear una instancia si aún no hay una instancia disponible
  • La declaración del constructor debe permitir modificar su cadena de prototipo. Esto permitirá al constructor heredar de otros prototipos y ofrecer métodos "públicos" para la instancia

Mi código es muy similar al de @zzzzBov, excepto que he agregado una cadena de prototipos al constructor y más comentarios que deberían ayudar a los que vienen de PHP o un lenguaje similar a traducir la POO tradicional a la naturaleza prototípica de Javascripts. Puede que no sea el "más simple" pero creo que es el más apropiado.

// 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''

Tenga en cuenta que técnicamente, la función anónima autoejecutable es en sí misma un Singleton, como se demuestra muy bien en el código proporcionado por @CMS. El único problema aquí es que no es posible modificar la cadena de prototipo del constructor cuando el propio constructor es anónimo.

Tenga en cuenta que para Javascript, los conceptos de "público" y "privado" no se aplican como lo hacen en PHP o Java. Pero hemos logrado el mismo efecto al aprovechar las reglas de disponibilidad de alcance funcional de Javascript.


A continuación se muestra el fragmento de mi recorrido para implementar un patrón singleton. Esto se me ocurrió durante un proceso de entrevista y sentí que debería capturar esto en algún lugar.

/************************************************* * SINGLETON PATTERN IMPLEMENTATION * *************************************************/ //since there are no classes 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 mismo se puede encontrar en mi página gist


Creo que el enfoque más limpio es algo como:

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; } }; })();

Después, puede invocar la función como

var test = SingletonClass.getInstance();


Creo que he encontrado la forma más limpia de programar en JavaScript, pero necesitarás algo de imaginación. Obtuve esta idea de una técnica de trabajo en el libro "javascript the good parts".

En lugar de utilizar la nueva palabra clave, puede crear una clase como esta:

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; }

Puede crear una instancia del objeto anterior diciendo:

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

Ahora, con este método de trabajo en mente, puedes crear un singleton como este:

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 }; }();

Ahora puedes obtener tu instancia llamando

var obj = ClassSingleton.getInstance();

Creo que esta es la mejor manera ya que ni siquiera se puede acceder a la "Clase" completa.


Creo que la forma más fácil es declarar un objeto literal simple:

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

Si quieres miembros privados en tu instancia de singleton, puedes hacer algo como esto:

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

Esto se ha denominado patrón de módulo , básicamente le permite encapsular miembros privados en un objeto, aprovechando el uso de closures .


Dejo de lado mi respuesta, veo mi otra .

Por lo general, el patrón de módulo (ver la respuesta de CMS) que NO es patrón de singleton es suficientemente bueno. Sin embargo, una de las características de Singleton es que su inicialización se retrasa hasta que se necesita el objeto. El patrón del módulo carece de esta característica.

Mi propuesta (CoffeeScript):

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

Que compiló a esto en JavaScript:

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

Entonces puedo hacer lo siguiente:

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


Descubrí que lo siguiente es el patrón Singleton más fácil, porque el uso del nuevo operador hace que esté disponible inmediatamente dentro de la función, eliminando la necesidad de devolver un objeto literal:

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


En 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


Hay más de una forma de despellejar a un gato :) Dependiendo de su gusto o necesidad específica, puede aplicar cualquiera de las soluciones propuestas. Personalmente, elijo la primera solución de CMS siempre que sea posible (cuando no necesita privacidad). Ya que la pregunta era sobre el más simple y limpio, ese es el ganador. O incluso:

var myInstance = {}; // done!

Esto (cita de mi blog) ...

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

no tiene mucho sentido (el ejemplo de mi blog tampoco) porque no necesita vars privados, por lo que es más o menos lo mismo que:

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


La respuesta más clara debería ser esta del libro Learning JavaScript Design Patterns de 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; } }; })();


Los siguientes trabajos en el nodo v6.

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

Nosotros probamos

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


Me gusta usar una combinación de Singleton con el patrón del módulo, ramificación de tiempo de inicio con un cheque Global NS, envuelto dentro de un cierre. En un caso en el que el entorno no va a cambiar después de la inicialización del singleton; El uso de un literal de objeto invocado de inmediato para devolver un módulo lleno de utilidades que persistirán por algún tiempo debería ser correcto. No estoy pasando ninguna dependencia, solo invoco los singletons dentro de su pequeño mundo, el único objetivo es: crear un módulo de utilidades para el enlace / desvinculación de eventos (la orientación del dispositivo / los cambios de orientación también podrían funcionar en este 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 ) );


Necesitaba varios singletons con:

  • inicialización perezosa
  • parámetros iniciales

Y así fue con lo que se me ocurrió:

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 debe ser Array para que esto funcione, así que si tiene variables vacías, simplemente pase []

  • Usé el objeto de ventana en la función pero podría haber pasado un parámetro para crear mi propio alcance

  • los parámetros de nombre y construcción son solo Cadena para que la ventana [] funcione, pero con un simple tipo de comprobación de tipo, window.name y window.construct también son posibles.


No estoy seguro de estar de acuerdo con el patrón del módulo que se utiliza como reemplazo de un patrón de singleton. A menudo he visto singletons utilizados y abusados ​​en lugares donde son totalmente innecesarios, y estoy seguro de que el patrón del módulo llena muchos huecos donde los programadores usarían un singleton, sin embargo, el patrón del módulo no es un singleton.

patrón de módulo:

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

Todo lo inicializado en el patrón del módulo sucede cuando se declara Foo . Además, el patrón del módulo se puede utilizar para inicializar un constructor, que luego se puede crear una instancia de varias veces. Si bien el patrón del módulo es la herramienta correcta para muchos trabajos, no es equivalente a un singleton.

patrón de singleton:

forma corta

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 larga, utilizando patrón de módulo.

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; }());

En ambas versiones del patrón Singleton que he proporcionado, el propio constructor se puede utilizar como el descriptor de acceso:

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

Si no te sientes cómodo usando el constructor de esta manera, puedes lanzar un error en la sentencia if (instance) y seguir usando el formulario largo:

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

También debo mencionar que el patrón de singleton encaja bien con el patrón de función constructora implícita:

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


No estoy seguro de por qué nadie mencionó esto, pero podrías simplemente hacer:

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


Patrón del módulo: en "estilo más legible". Puedes ver fácilmente qué métodos son públicos y cuáles son privados

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");

Ahora puedes usar métodos públicos como

module.method2 (); // -> Estoy llamando a un método privado sobre una alerta de método público ("hi im a private method")

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


Puedes hacerlo con decoradores como en este ejemplo a continuación para TypeScript:

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

Entonces usas tu singleton así:

var myInstance = YourClass.singleton();

A partir de este escrito, los decoradores no están disponibles en los motores de JavaScript. Debería asegurarse de que su tiempo de ejecución de JavaScript tenga los decoradores realmente habilitados o usar compiladores como Babel y TypeScript.

También tenga en cuenta que la instancia de singleton se crea "perezosa", es decir, se crea solo cuando la usa por primera vez.


Recibí este ejemplo de JavaScript Patterns Cree mejores aplicaciones con codificación y patrones de diseño Por el libro de Stoyan Stefanov , en caso de que necesite alguna clase de implementación simple como el objeto singltone, puede usar la función inmediata de la siguiente manera:

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 // i.e.: this.someProperty = 0; this.someMethod = function() { //Some action here }; }; }());

Y puedes verificar este ejemplo siguiendo el caso de prueba:

//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

Este enfoque pasa todos los casos de prueba, mientras que la implementación estática privada fallará cuando se use la extensión del prototipo (se puede arreglar pero no será simple) y la implementación estática pública será menos aconsejable debido a que la instancia está expuesta al público.

demo jsfiddly


Aquí está el ejemplo simple para explicar el patrón de singleton en el 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();


Semifallo:

Asegúrese de que una clase tenga solo una instancia y proporcione un punto global de acceso a ella.

El patrón Singleton limita la cantidad de instancias de un objeto en particular a solo una. Esta única instancia se llama el singleton.

  • define getInstance () que devuelve la instancia única.
  • responsable de crear y gestionar el objeto de instancia.

El objeto Singleton se implementa como una función anónima inmediata. La función se ejecuta de inmediato envolviéndola entre paréntesis seguida de dos corchetes adicionales. Se llama anónimo porque no tiene nombre.

Programa de muestra,

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()


Creo que esta es la forma más sencilla / limpia e intuitiva, aunque requiere ES7:

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

El código fuente es de: adam-bien.com


La clave principal es entender la importancia del cierre detrás de esto. Por lo tanto, las propiedades incluso dentro de la función interna serán privadas con la ayuda del cierre.

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; } };

};


No dijiste "en el navegador". De lo contrario, puede utilizar módulos NodeJS . Estos son los mismos para cada requirellamada . Ejemplo básico:

Los contenidos de foo.js:

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

Los contenidos de circle.js:

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

Tenga en cuenta que no puede acceder circle.PI, ya que no se exporta.

Si bien esto no funciona en el navegador, es simple y limpio.


Singleton en javascript se logra mediante el uso de patrones y cierres de módulos. A continuación se muestra el código que se explica por sí mismo:

// 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.


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