Hacker News .hnnew | past | comments | ask | show | jobs | submitlogin

This enumeration is done the wrong way. You enumerate over a DOM node list which looks like an array, which includes enumerable properties like "length". This means that the variable "p" at some point will be "length" and "length".innerHTML = "..." will produce an error.

The proper way is:

for( var i=0, ps=document.getElementsByTagName('p'), len=ps.length; i < len; i++) {ps[i].innerHTML = 'Hello.';}



I'm a JS noob, but I though 'length' was not enumerable (i.e. its 'enumerable' property is set to 'false').

Edit: I think I missed what you said. You're saying it's "like" and array, but unlike arrays its `length` is enumerable. I'll leave my comment so other skeptics can benefit :)

Edit2: This is what I was referring to (read the 'Note' at the right side): http://bonsaiden.github.com/JavaScript-Garden/#object.forinl...


Looks like this is correct:

paras = document.getElementsByTagName('p') for (var para in paras) { console.log(para)} 0 1 ... 9 10 length item


That's ES3. You have no reason to choose that way anymore - ES5 loops work everywhere current, can be polyfilled into IE8, and don't require any boilerplate stuff.

var paragraphs = document.getElementsByTagName('p');

paragraphs.forEach(function(paragraph){paragraph.innerHTML = 'Hello.';})


This will not work - Check my solution below :)

document.getElementsByTagName returns a DOM Node List and it does not have forEach method according to the DOM spec. DOm Nodes, Elements and Node Lists and Node Maps do not follow the javascript spec (ECMAScript) hence do not share methdos and properties. A Dom Node List does not have the methods of the javascript array. That is because DOM Node List does not inherit from the Array.prototype, because it is not javascript - it has its own spec that exactly determines what methods and properties it should have. The implementation in the browser happens to be accessible through javascript but that does not mean that the DOM is part of javascript. That is why wrapper libraries like jQuery or other abstractions are necessary to make the DOM much more accessible from a JS perspective. BTW that is why many people confuse DOM with javascript and then get frustrated which is understandable.


Except #forEach is a method of Array, and getElementsByTagName does not return an Array but a NodeList. Which doesn't have any of Array's methods (it has a length, it can be indexed, and it has an alternative indexation method - #item — but it's not an array at all)


You're right. I wasn't sure earlier, as I was typing on a phone with no JS console.

but never mind:

Array.forEach.call(paragraphs, function(paragraph){paragraph.innerHTML = 'Hello.';})

will work fine.


Ah, thanks for the correction! I just wrote it out from memory, and it's been a while since I used Vanilla-JS DOM selectors ;)


Try this in a browser. On Webkit at least is also returns length and item:

for (var p in document.getElementsByTagName('p')) {console.log(p);}




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: