...

View Full Version : Favorite JS Patterns



jkd
06-24-2008, 04:55 AM
A few of mine:

"Adding" to a function after definition:


window.onload = (function(onload) {
return function() {
// add stuff before the original function by putting it here
onload.apply(this, arguments);
// add stuff after the original function by putting it here
}
})(window.onload);

Not just nice for old-school listeners, but also for big DHTML things, I put possibly-incompatible code into instance methods, then overwrite the instance methods on a per browser, per hack basis.


The Self-Destructing Listener:


node.addEventListener("someevent", function(event) {
if (somecondition) {
// do stuff
}
else {
// remove listener
node.removeEventListener("someevent", arguments.callee, false);
}
}, false);

I've used this one most recently on an Excel-clone in JS, where I had to maintain formulas. On registering a cell with a formula, I add change listeners to each cell it depends on. If the user modifies the formula cell (or removes it), then the listeners eventually take care of themselves -- my condition is comparing a string of the old formula with the current formula.

It is important to note that the memory isn't freed immediately, but you're also not using extra memory for some messy grid data structure to maintain the formula connections.

Also, it is just as easy to replace (add|remove)EventListener with (attach|detach)Event ;).

Any of you guys/girls have some gems in your toolbox?

Trinithis
06-24-2008, 06:11 AM
Not my favorite patterns (I can't think of any on the top of my head), but here are some interesting ones.

Named parameters with default values:


Object.combine = function() {
for(var r = {}, i = arguments.length - 1, x; i >= 0; --i)
for(x in arguments[i])
if(arguments[i].hasOwnProperty(x))
r[x] = arguments[i][x];
return r;
}

function foo(args /* {day, month, year} */) {
args = Object.combine(args || {}, {day: 1, month: 1. year: 1});
alert(args.month + args.day + args.year);
}

foo({year: 2000, day: 30, month: 4});
foo({day: 13});
foo();

Useful if keeping track of parameter order is difficult. Giving default values this way is just an extra bonus. (I think its easier than doing a bunch of ||s or if-statements for defaulting.)

valueOf objects:


var counter = {
val: 1,
valueOf: function() {
return this.val++;
}
};

var x = 10 + counter; // x = 11
var y = 100 + counter; // y = 102

I have occasionally used this pattern in place of using closures to do the same thing. A similar pattern exists using toString instead of or in addition to valueOf.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum