Singleton without a closure
Warning: anti-pattern ahead.
Mwahaha, I feel like a ninja. I mean a ninja by Doug Crockford's definition which means someone who finds a mistake in the language's design, decides it's cool and abuses it.
So there you go. Regular expression objects are created only once if you're using a literal. Such an object can be used to store the single instance of a Singleton() constructor.
Implementation
function Single() { "strict me not!"; var re = / /; if (re.instance) { return re.instance; } re.instance = this; this.name = "Foo"; } Single.prototype.getName = function () { return this.name; };
Test
var s1 = new Single(), s2 = new Single(); console.log(s1 === s2); // true console.log(s1.getName()); // "Foo" s1.name = "dude"; console.log(s2.getName()); // "dude"
Pros
- The prototype chain works fine
- No closures
- No public properties or globals to store the single instance
Cons
- It's a hack
- ES5 defines that reg exp literals should no longer work like this
Verdict
Don't use. Please
Tags: singleton
July 18th, 2010 at 5:54 am
Lol. Why not:
function Single() {
"strict me not!";
if (Single.instance) {
return Single.instance;
}
Single.instance = this;
this.name = "Foo";
}
July 18th, 2010 at 2:50 pm
At least IE, Safari, and Opera all fail this pattern because they evaluate the literal each time. Balázs’ suggestion is better.
var Single = (function() {
function Klass() { };
function Single(name) {
one.name = name || 'Foo';
return one;
}
var one = new Klass;
Single.prototype = Klass.prototype;
return Single;
})();
Single.prototype.getName = function () {
return this.name;
};
The it works cross-browser, the instance isn’t stored as an external property, and it allows `Single` to work when called as function or a constructor.
July 18th, 2010 at 3:06 pm
For a flavor more in line with the pattern you are trying to achieve:
var Single = function(name) {
function Klass() { };
function Single(name) {
name && (one.name = name);
return one;
}
Single.prototype = Klass.prototype = window.Single.prototype;
window.Single = Single;
var one = new Klass;
return Single(name);
};
Single.prototype.name = 'Foo';
Single.prototype.getName = function () {
return this.name;
};
December 18th, 2011 at 3:53 am
Its like you read my mind! You seem to know a lot about this, such as you wrote the e book in it or something. I believe that you just can do with some percent to force the message home a bit, however instead of that, that is great blog. A fantastic read. I’ll definitely be back.