I try to understand javascript design patterns. I created an example of a 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)
I can not understand why a === b is true, but {name: 'name'} === {name: 'name'} is false. I now that in the last situation when we compare 2 objects they always will be different even if they have same proprieties, because they point to different memory places. But also i expect afalse when i compare a === b, because in fact a ={data: 'test'} and b ={data: 'test'}, so at the end we have the same situation as in the previous situation, but different results. Who can explain this?
because your constructor is always returning the same object, in your example, doing the same you do with the class, it would be:
const a = {name: 'name'}
const b = a;
console.log(a === b) // true
also const b = new App('car'); will not work. it will also get the class initiated with new App('test').
what you may want:
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) // false
It's because if you return an object out of a constructor, the result of the new is the object you return, not the new object that was being created.
Your code does that by setting (initially) and then returning App.instance, so only the first instance of App you create will ever be returned by the constructor, all the others will be thrown away.
We can see that in action if we modify the example a bit:
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;
}
As you can see, during the second call to new App where we pass in a, a new instance was created (this === previous? false), but the earlier one was returned.
There is one singleton and which is calling twice. You have one class having static variable instance. It will be created only once in the application life cycle. Following code lines will be executed on first time.
App.instance = this
return App.instance
For second time or later, above code will not be accessible because of the following code
if (App.instance) {
console.log("Returning previous App.instance");
return App.instance
}
Here code is returning the same object which was created on first time. So actually same object returns on second and later calling. That is why reference of object remains same every time you call it.