Tuesday, March 20, 2007

for in loop prototype safe

In many different libraries there should be one or more prototype method for every native JavaScript constructor.

Every time You do a for in loop
for(var key in object) ...

You probably need to check object[key].

Add prototype to Object constructor is never a good practices, but for in loop can be used with other native constructors too, as example, Array.


Array.prototype.randomValue = function(){
return this[Math.floor(Math.random() * this.length)];
};

var myArray = [1, 2, 3];
alert(myArray.randomValue()); // 1 or 2 or 3


The common way to loop over an array is a loop that uses index integer values but sometime You should need to loop over a generic variable just using a for in loop.


for(var key in myArray) {
// dostuff
}

In this case the "randomValue" key is part of loop but You can't know everytime wich library add its Array prototype so this is my simple proposal, the $for function.

function $for(obj, callback){
var proto = obj.constructor.prototype,
h = obj.hasOwnProperty, key;
for(key in obj) {
if((h && h.call(obj,key)) || proto[key] !== obj[key])
callback(key, obj[key]);
}
};

With these few lines of code You can perform a for in loop without prototype problems, for example:

var myArray = [1, 2, 3],
total = 0;
$for(myArray, function(key, value){
total += value;
});
alert(total);

Used function is automatically cached by $for one so I think this kind of loop will be fast enought (expecially working with internal scope).

Do You like this prototype safe solution? I hope so :)

No comments:

Post a Comment