Friday, August 3, 2012

The arguments.callee Debate

OK, I'll admit I can sometimes be "late to the game" on some things.  Specifically, I realize that the whole arguments.callee/singleton design pattern/deprecation in Javascript debate is about two years old.  However, I think this is one of those things that generally is worth mentioning (and consequently giving more fuel  and attention to).


As many of you know, I started a new gig at VEVO this past June as a web developer.  In other words, I'm moving away from Actionscript and more towards Javascript.  Don't get me wrong; I'm still true to my AS3/PHP/OOP roots but JS is where it's at right now so I needed to make a change.  One of the things I needed to figure out first is how to convert my design patterns over to JS, specifically the infamous Singleton.  Given the fact that JS is a loosely typed language, this wasn't going to be easy.
After much research, I created the following example:

function SingletonClass(nme,clr){
 if (arguments.callee.instance){return arguments.callee.instance;}
 arguments.callee.instance = this;
 this.name = nme;
 this.color = clr;
}

SingletonClass.prototype.setColor = function(clr){
 this.color = clr;
}

SingletonClass.prototype.setName = function(nme){
 this.name = nme;
}

var singleton1 = new SingletonClass('firstSingleton','black');
console.log('(singleton1): My name is ' + singleton1.name + ' and my color is ' + singleton1.color + '.');

var singleton2 = new SingletonClass('secondSingleton','green');
console.log('(singleton2): My name is ' + singleton2.name + ' and my color is ' + singleton2.color + '.');

singleton2.setColor('blue');
singleton2.setName('Matt');

console.log('(singleton1): My name is ' + singleton1.name + ' and my color is ' + singleton1.color + '.');

This works beautifully, with one small exception; arguments.callee has been deprecated.  If you're like me, you're immediately thinking, "WHAT?????" right about now.  After a bit of research, I found the following bug reports:
However, this doesn't solve the problem.  The fact is, currently this is deprecated so if you want to create a true Singleton, a bit of adjustment is necessary.  Given that, I came up with the following:

var SingletonInstance;

function SingletonClass(nme,clr){
 if(SingletonInstance){return SingletonInstance;}
 SingletonInstance = this;

 this.name = nme;
 this.color = clr;
}

SingletonClass.prototype.setColor = function(clr){
 this.color = clr;
}

SingletonClass.prototype.setName = function(nme){
 this.name = nme;
}

var singleton1 = new SingletonClass('firstSingleton','black');
console.log('(singleton1): My name is ' + singleton1.name + ' and my color is ' + singleton1.color + '.');

var singleton2 = new SingletonClass('secondSingleton','green');
console.log('(singleton2): My name is ' + singleton2.name + ' and my color is ' + singleton2.color + '.');

singleton2.setColor('blue');
singleton2.setName('Matt');

console.log('(singleton1): My name is ' + singleton1.name + ' and my color is ' + singleton1.color + '.');

Yes, this is not necessarily the same thing but if you run it, you'll see that it does indeed accomplish the same goal.  I wanted to share this so that others who are looking for a Javascript Singleton pattern "starter kit" can hopefully use my work as a launch pad.

No comments:

Post a Comment