Trying to implement the singleton pattern within CommonJS modules, using Browserify. So far:
// foo.js
var instance = null;
var Foo = function(){
if(instance){
return instance;
}
this.num = 0;
return instance = new Foo();
}
Foo.prototype.adder = function(){
this.num++;
};
module.exports = Foo();
// main.js
var foo = require('./foo.js');
console.log(foo.num); // should be 0
foo.adder(); // should be 1
var bar = require('./foo.js');
console.log(bar.num); // like to think it'd be 1, not 0
First problem is that I get a maximum call stack exceeded
error when I load the built JS file in the browser, but secondly, am I approaching this correctly? Is this possible?
Well, that comes from your
Foo
function recursively callingnew Foo
…No. For singletons, you don't need a "class" with a constructor and a prototype - there will only ever be one instance. Simply create one object, most easily with a literal, and return that:
The result of any require call is a singleton -- whether a singleton instance or a singleton function or a singleton factory function. Furthermore, a require call should be idempotent -- poorly written CommonJS modules may violate this, so if a CommonJS module has a side effect, that side effect should happen only once no matter how many times that require is called.
The code snippet you have
is a legacy of the kinds of hoops you'd have to jump through if you were using plain old JavaScript to create singletons. It's totally unnecessary when using CommonJS and besides that, it leads to your
maximum call stack exceeded
issue.Your code could be rewritten like this:
or even more succinctly:
because putting the
adder
method on the prototype doesn't gain you any real efficiency if you're only creating a single instance of Foo, and because you don't need to hide anything in the closure.