views:

307

answers:

8

Given some JS code like that one here:

  for (var i = 0; i < document.getElementsByName('scale_select').length; i++) {
    document.getElementsByName('scale_select')[i].onclick = vSetScale;
  }

Would the code be faster if we put the result of getElementsByName into a variable before the loop and then use the variable after that?

I am not sure how large the effect is in real life, with the result from getElementsByName typically having < 10 items. I'd like to understand the underlying mechanics anyway.

Also, if there's anything else noteworthy about the two options, please tell me.

+1  A: 

In principle, would the code be faster if we put the result of getElementsByName into a variable before the loop and then use the variable after that?

yes.

nickf
A: 

I think so. Everytime it loops, the engine needs to re-evaluate the document.getElementsByName statement.

On the other hand, if the the value is saved in a variable, than it allready has the value.

Ikke
+14  A: 

Definitely. The memory required to store that would only be a pointer to a DOM object and that's significantly less painful than doing a DOM search each time you need to use something!

Idealish code:

var scale_select = document.getElementsByName('scale_select');
for (var i = 0; i < scale_select.length; i++)
    scale_select[i].onclick = vSetScale;
Oli
Thanks for being so precise!
Hanno Fietz
And if you're worried about long-term memory costs, you can release the variable: scale_select = null;
Oli
"delete scale_select" will also remove it - plus it is much more obvious what your intentions are.
nickf
Fair point, nickf. I didn't know about delete and now I do. Thanks for teaching me something new today =)
Oli
Just don't try to delete DOM node properties in IE (even ones you added ). Fatal Error Occurs :)
Kent Fredric
delete scale_select; will not do anything. delete can only be used on object properties, e.g., delete obj.foo;
noah
ditto - delete is for deleting properties from objects, not for clearing variables, per se.
Jason Bunting
i just tested this code: var a = "abc"; alert(a); delete a; alert(a); and that alerts "abc" and then "undefined". So it looks as though it DOES work. (at least on Firefox 3)
nickf
Thanks for the follow-up nick!
Oli
+1  A: 

Use variables. They're not very expensive in JavaScript and function calls are definitely slower. If you loop at least 5 times over document.getElementById() use a variable. The idea here is not only the function call is slow but this specific function is very slow as it tries to locate the element with the given id in the DOM.

How did you come up with 5 as the magic number?
Andrew Hedges
+3  A: 

A smart implementation of DOM would do its own caching, invalidating the cache when something changes. But not all DOMs today can be counted on to be this smart (cough IE cough) so it's best if you do this yourself.

pcorcoran
+3  A: 

Caching the property lookup might help some, but caching the length of the array before starting the loop has proven to be faster.

So declaring a variable in the loop that holds the value of the scale_select.length would speed up the entire loop some.

var scale_select = document.getElementsByName('scale_select');
for (var i = 0, al=scale_select.length; i < al; i++)
    scale_select[i].onclick = vSetScale;
ScottKoon
A: 

@ Oli

Caching the length property of the elements fetched in a variable is also a good idea:

var scaleSelect = document.getElementsByName('scale_select');
var scaleSelectLength = scaleSelect.length;

for (var i = 0; i < scaleSelectLength; i += 1)
{
    // scaleSelect[i]
}
roosteronacid
+1  A: 

There's no point storing the scaleSelect.length in a separate variable; it's actually already in one - scaleSelect.length is just an attribute of the scaleSelect array, and as such it's as quick to access as any other static variable.