var elist = document.getElementsByTagName("img"); elist.forEach( function(e){ if( e.naturalWidth==0 ) e.src += "#"; });
これはエラーになる。
getElementsByTagName()の戻り値をぐるぐる回すときに、forEachを使うとエラーになる。これは、getなんとか系の戻り値がArrayではなくNodeListのため。
getElementsByTagName:mx-Lab:So-netブログ
Q: iterating over result of getElementsByClassName using Array.forEach
JS: iterating over result of getElementsByClassName using Array.forEach | ansaurus
A: It does not return an Array, it returns a NodeList.
elements = element.getElementsByTagName(tagName)
Element.getElementsByTagName() - Web APIs | MDN
elements is a live NodeList (but see the note below)
※実際のところfirefox19以降ではHTMLCollectionが返る。 W3C DOM3ではNodeList返す仕様で、DOM4ではHTMLCollection返す予定いうのがその理由だが、バグとみなされてる。
配列ライクなオブジェクトをforEachするときのイディオム - ぷちてく - Petittech
こう書けば思ったとおりに動作するようになる
var elist = document.getElementsByTagName("img"); Array.prototype.forEach.call( elist, function(e){ if( e.naturalWidth==0 ) e.src+="#"; });
(document.querySelectorAll('*')).forEach ? · GitHub
ArrayのようにforEachを使いたい時は、メソッドを定義して使う。
NodeList.prototype.forEach = Array.prototype.forEach; HTMLCollection.prototype.forEach = Array.prototype.forEach; var elist = document.getElementsByTagName("img"); elist.forEach( function(e){ if( e.naturalWidth==0 ) e.src += "#"; });
しかし、ふつうのfor文で書いた方が 見やすいしどこでも動くし速い
Investigating JavaScript Array Iteration Performance | BenHollis.net