The World Through the Eyes of John Brennan
I’ve been using Prototype + Scriptaculous for my current project. It surprises me that I haven’t encountered this problem until just now though.
I noticed some funky behavior today when I tried iterating over an array of values. I have loved Prototype for some time. It’s elegant style, ease of DOM manipulation, and ummm.. it’s style!
However, the behavior I just encountered I don’t care for. I know that Prototype modifies (extends) the builtin objects of Javascript, namely Array and Object. I like the added bang for the buck that I get. But look at this test:
var l_a = ["A","B","C"]; var l_r = ""; for(var l_x in l_a){l_r += l_x + " ";} alert((l_r == "0 1 2 ") + "\n" + l_r);
What do you think that prints out? Chances are you’re wrong. It actually prints out the array… followed by all the functions used to extend the Array object.
false 0 1 2 each eachSlice all any collect detect findAll grep include inGroupsOf inject invoke max min partition pluck reject sortBy toArray zip size inspect find select member entries _reverse _each clear first last compact flatten without reduce uniq clone toJSON call
The same sort of problem happens if you were to use object literals instead of arrays. Let me show you the bad and good ways to use each of them.
var l_a = ["A","B","C"]; var l_r = ""; for(var l_x in l_a){l_r += l_x + " ";} alert((l_r == "A B C ") + "\n" + l_r); Output: false A B C each eachSlice all any collect detect findAll grep include inGroupsOf inject invoke max min partition pluck reject sortBy toArray zip size inspect find select member entries _reverse _each clear first last compact flatten without reduce uniq clone toJSON call
var l_a = ["A","B","C"]; var l_r = ""; for(var l_x = 0;l_x < l_a.length;l_x++){l_r += l_a[l_x] + " ";} alert((l_r == "A B C ") + "\n" + l_r); Output: true A B C
var l_a = {}; l_a["a"] = "A"; l_a["b"] = "B"; l_a["c"] = "C"; var l_i; var l_r = ""; for(var l_x = 0;l_x < l_a.length;l_x++){l_r += l_a[l_x] + " ";} alert((l_r == "A B C ") + "\n" + l_r); Output: false
var l_a = {}; l_a["a"] = "A"; l_a["b"] = "B"; l_a["c"] = "C"; var l_i; var l_r = ""; for(var l_x in l_a){l_r += l_x + " ";} alert((l_r == "a b c ") + "\n" + l_r); Output: true a b c
When using arrays always iterate over the elements with:
for(var l_x = 0;l_x < l_a.length;l_x++){}
When using object literals always iterate over the elements with:
for(var l_x in l_a){}
Code. Design. Explore. is the blog of John Brennan, a web developer/designer, entrepreneur, and avid world traveler. I currently live in Brooklyn, NY.
I am the Co-Founder of OpenAction and lead Product Development. We are a open platform social enterprise that helps organizations engage with donors, share knowledge with other non profits and empower the community to get involved to create positive impact on our planet.
This blog will mostly be around building cool things, although I will surely include my travel experiences when I am abroad. Feel free to subscribe to a specific category if that is only what interests you. And please connect with me. I always enjoy meeting new, interesting people!
Leave a reply