揮発性のメモ2

http://d.hatena.ne.jp/iww/

getElementsByTagName()の戻り値はブラウザによって違う

    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
A: It does not return an Array, it returns a NodeList.

JS: iterating over result of getElementsByClassName using Array.forEach | ansaurus

elements = element.getElementsByTagName(tagName)
elements is a live NodeList (but see the note below)

Element.getElementsByTagName() - Web APIs | MDN

※実際のところ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