Monday, August 3, 2009

Short-cutting With JavaScript :)

JavaScript is a very underestimated language, but it’s nice to see that a lot of developers out there have learned the potential of the language, and some others, lest them be known, I avoided arguments with them when they have had a vague idea of what it does, and tried to argue with me that JavaScript is worthless.
Now, let’s get to the point.
Let’s say you want something like this:
function foo(msg) {
alert(arguments.callee.name + ': ' + msg);
}

function bar(msg) {
alert(arguments.callee.name + ': ' + msg);
}

function baz(msg) {
alert(arguments.callee.name + ': ' + msg);
}

function doit(param) {
if (param === 'foo')
foo(param);

else if (param === 'bar')
bar(param);

else if (param === 'baz')
baz(param);
}

doit('bar');

That’s a lot of checking. If the code is cleaned up a bit by wrapping the functions in an object, then we could replace the content of the doit function with just one line of code. Here’s how:
var wrapper = {
foo: function(msg) {
alert('foo: ' + msg);
},

bar: function(msg) {
alert('bar: ' + msg);
},

baz: function() {
alert('baz: ' + msg);
}
};

function doit(param) {
wrapper[param](param);
}

doit('bar');

This will output the same as the Example 1.

Just for kicks, we can go even crazier by automating the creation of the functions and stuff, this is just to show the potential of JavaScript, probably won’t be that effective in real world, but it could be, all depends on how you use what.
var wrapper = {}; // Initialize the wrapper
var fn = [ 'foo', 'bar', 'baz' ]; // Set the function names in an array

for (var i in fn) {
// String name of function is passed as a new property for wrapper
wrapper[fn[i]] = function(msg) { // and is assigned as a function
// I'm still trying to find a way to get the name of the function in here
alert(msg);
};
}

wrapper['bar']('bar');

Of course this example is just a quickie.

OK, Example 3 aside, the only disadvantage of wrapping the functions — as in Example 2 — is that you can’t access the name of the function with arguments.callee for further automation; as you saw in Example 3, I wasn’t able to print the function name, and in Example 2 I printed them manually.

What we could do in this case is merge Example 1 & 2:
function foo(msg) {
alert(arguments.callee.name + ': ' + msg);
}

function bar(msg) {
alert(arguments.callee.name + ': ' + msg);
}

function baz(msg) {
alert(arguments.callee.name + ': ' + msg);
}

// Hook up each wrapper property to a function
var wrapper = { foo: foo, bar: bar, baz: baz };

function doit(param) {
wrapper[param](param);
}

doit('bar');

Yes, of course, the floating around functions. Clean things up by wrapping in an anonymous function:
(function() {
function foo(msg) {
alert(arguments.callee.name + ': ' + msg);
}

function bar(msg) {
alert(arguments.callee.name + ': ' + msg);
}

function baz(msg) {
alert(arguments.callee.name + ': ' + msg);
}

var wrapper = { foo: foo, bar: bar, baz: baz };

function doit(param) {
wrapper[param](param);
}

doit('bar');
})();

If anyone knows of a way to get the property name please leave a comment :)

0 comments: