My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Wednesday, January 24, 2007

bored with something to array convertion ? map them !

I'm rewriting my JSL to include by default inside my next project.
This project will include automatically a lot of standard JS 1.5 methods or functions, and is one of those.

While I'm testing some proto performances, I've thought about a really simple way to switch from an array or from a node list (getElementsByTagName) with a simple, fast and single line of function.

// old example version
// function _A(a){return [],function(a){return a})};

// new version, Daniel suggest, faster and doesn't require any prototype !
function _A(a){return []};

and that's all, do You like it ?

As first point, You need FireFox 1 or greater (or Mozilla if You prefere) or this short piece of code:

if(! = function(callback){
for(var i = 0, j = this.length, result = new Array(j), self = arguments[1], u; i < j; i++) {
if(this[i] !== u)
result[i] =, this[i], i, this);
return result;

Then You have "everything You need" to get quickly every iterable element.

These are just two examples

function sort(){
return _A(arguments).sort().join("<br />");
document.writeln(sort("Luke", "Jabba", "Fenner"));
document.writeln(sort("c", "a", "b"));

var firstScript = _A(document.getElementsByTagName("script")).shift();

var allUnorderedList = _A(document.getElementsByTagName("ul"));

alert(_A(null).constructor === Array); // true ;-)

These nice trick should be used with forEach method too.
Stop for and while loops, each them !

function changeLinks(onclick){
link.onclick = onclick;

changeLinks(function(){, "");
return false;

... and sure, You need forEach prototype too ...

I suppose every other JS 1.5 Array method should be cool enought to work with DOM nodes too ... do You agree ?

Are thinking about performances ? Well guys, quite the same of generic loops, even faster (works in core) with every FireFox !!!


Daniel said...

You can use slice to create arrays. I think '' works for node lists on Firefox and Opera 9, but not Safari (I can't remember if it works on Internet Explorer). So I would sniff the browser and the version and only use it when 100% sure that it is supported.

Andrea Giammarchi said...

sure Daniel, You can use every type of array prototype and slice should be even better (suported on IE4 too)

function _A(a){return []};

why not ... it's cool but with map, forEach or filter You should use directly a callback to parse every object inside each arguments (and with map prototype You'll be shure browser will support them witho nodeLists too ;-))

However, how many libraries use this "tips" ? ... look inside prototype code, for example, You'll see a for loop while $A function should be:
function $A(i){return i&&i.toArray?i.toArray():[]};

Do You agree ? :-)

Andrea Giammarchi said...

Well ... seems that IE doesn't accept this trick with document nodes ... strange, uh ?