I came across this rather interesting way to create a JavaScript singleton that can be instantiated with the new
keyword, like var x = new SingletonClass()
. I have a pretty good grasp of variable scope and closures, etc., but I'm having a hard time understanding exactly why this block of code works the way it does.
// EDIT: DO NOT USE this code; see the answers below
function SingletonClass() {
this.instance = null;
var things = [];
function getInstance() {
if (!this.instance) {
this.instance = {
add: function(thing) {
things.push(thing);
},
list: function() {
console.log(things.toString());
}
};
}
return this.instance;
}
return getInstance();
}
var obj1 = new SingletonClass();
obj1.add("apple");
obj1.list(); //"apple"
var obj2 = new SingletonClass();
obj2.add("banana");
obj1.list(); //"apple,banana"
obj2.list(); //"apple,banana"
obj1.add("carrot");
obj1.list(); //"apple,banana,carrot"
obj2.list(); //"apple,banana,carrot"
My intuition says that each time a new SingletonClass
is instantiated, this
refers to that fresh new object -- but then since a totally separate object is returned by the constructor, I would figure this
would just get discarded. But it hangs around. How? Why?
There's some tiny little detail going on here that I'm missing. Can anybody shine some light on it?
EDIT: Turns out this code is bad. The reason why it "magically" seems to hold a reference to the instance is because it's actually silently storing it in the global object. It's bad practice at best, and undoubtedly bug-prone.
Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the instance of the class. Singleton pattern is used for logging, drivers objects, caching and thread pool.
Singletons are used to create an instance of a class if it does not exist or else return the reference of the existing one. This means that singletons are created exactly once during the runtime of the application in the global scope. Based on this definition, singletons seem very similar to global variables.
A singleton is a function or class which can have only one instance. It's a design pattern popularised by the “Gang of Four” in their influential Design Patterns. However, the singleton is one of several patterns in the book which have been criticised.
It is used where only a single instance of a class is required to control the action throughout the execution. A singleton class shouldn't have multiple instances in any case and at any cost. Singleton classes are used for logging, driver objects, caching and thread pool, database connections.
Don't confused by the this
inside the function getInstance
, that this
is the global object window
, so you are creating an object and assigned to the window object, and next time you call the constructor, you are checking whether window.instance
is existing.
The code this.instance = null;
is meanless, just confusing you. Remove it won't change anything.
The below is from the MDN.
When the code
new foo(...)
is executed, the following things happen:
- A new object is created, inheriting from foo.prototype.
- The constructor function foo is called with the specified arguments and this bound to the newly created object. new foo is equivalent to
new foo()
, i.e. if no argument list is specified, foo is called without arguments.- The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
Note the step3, when you have return statement in constructor, the returned result will be the result of the new expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With