Trato de entender los patrones de diseño de JavaScript. He creado un ejemplo de un singleton:
class App { constructor(data) { this.instance; this.data = data; if (App.instance) { return App.instance } App.instance = this return App.instance } } const a = new App('test'); const b = new App('car'); console.log(a === b) No puedo entender por qué a === b es true , pero {name: 'name'} === {name: 'name'} es false . Sé que en la última situación, cuando comparamos 2 objetos, siempre serán diferentes incluso si tienen las mismas propiedades, porque apuntan a diferentes lugares de memoria. Pero también espero un false cuando comparo a === b , porque de hecho a ={data: 'test'} y b ={data: 'test'} , así que al final tenemos la misma situación que en el situación anterior, pero resultados diferentes. ¿Quién puede explicar esto?
porque su constructor siempre devuelve el mismo objeto, en su ejemplo, haciendo lo mismo que hace con la clase, sería:
const a = {name: 'name'} const b = a; console.log(a === b) // true también const b = new App('car'); no trabajará. también iniciará la clase con new App('test') .
lo que puede desear:
const appInstances = {}; class App { public static getSingleton(key) { if(!appInstances[key]) { appInstances[key] = new App(key); } return appInstances[key]; } constructor(data) { this.data = data; } } const a = App.getSingleton('test'); const b = App.getSingleton('car'); console.log(a === b) // falseEs porque si devuelve un objeto de un constructor, el resultado de new es el objeto que devuelve, no el nuevo objeto que se estaba creando.
Su código lo hace configurando (inicialmente) y luego devolviendo App.instance , por lo que el constructor solo devolverá la primera instancia de App que cree, todas las demás se desecharán.
Podemos verlo en acción si modificamos un poco el ejemplo:
class App { constructor(data, previous) { if (previous) { console.log(`this === previous? ${this === previous}`); console.log(`this === App.instance? ${this === App.instance}`); console.log(`previous === App.instance? ${previous === App.instance}`); } this.instance; // This doesn't do anything, btw this.data = data; if (App.instance) { console.log("Returning previous App.instance"); return App.instance } console.log("Setting up and returning first App.instance"); App.instance = this return App.instance } } const a = new App("test"); /* Logs: Setting up and returning first App.instance */ const b = new App("car", a); /* Logs: this === previous? false this === App.instance? false previous === App.instance? true Returning previous App.instance */ console.log(a === b); .as-console-wrapper { max-height: 100% !important; } Como puede ver, durante la segunda llamada a la new App donde pasamos a , se creó una nueva instancia ( this === previous? false ), pero se devolvió la anterior .
Hay un singleton y que está llamando dos veces. Tiene una clase que tiene una instance de variable estática. Se creará una sola vez en el ciclo de vida de la aplicación. Las siguientes líneas de código se ejecutarán la primera vez.
App.instance = this return App.instancePor segunda vez o más tarde, no se podrá acceder al código anterior debido al siguiente código
if (App.instance) { console.log("Returning previous App.instance"); return App.instance }Aquí el código devuelve el mismo objeto que se creó la primera vez. Entonces, en realidad, el mismo objeto regresa en la segunda y posterior llamada. Es por eso que la referencia del objeto permanece igual cada vez que lo llama.