HTMLCollectionがiterableかどうかの検証

突然ですが、Chrome、Safari、Firefox、Microsoft Edgeの中で
以下のコードが動かないものが一つだけあります。

<script>
for (let element of document.getElementsByTagName(‘div’)) {
     console.log(element)
}
</script>

やはり。。。

このWEB業界に長年関わってきた皆様ならば、すぐにお察しが付くだろうと思います。
上記のコードが動かないのは、Microsoft Edgeのみです。

Microsoft Edge

ChromeやSafari、Firefoxは無事に動作します。

ただEdgeは既にECMAScript 2016(JavaScriptの仕様) には完全対応しているため、
for-of ステートメントは問題なく使用できます。
しかしエラー文 Object doesn’t support property or method ‘Symbol.iterator’ を読みますと
document.getElementsByTagName()メソッドで返されるHTMLCollectionがイテレーブルでないことが原因のようです。
(for-ofステートメントで要素を取り出せるのは、イテレーブルである必要があります。)

だがしかし、Microsoftは間違っていなかった。。。

document.getElementsByTagName()メソッドがHTMLCollectionを返す仕様は、2015年に完全発行されたDOM Level4で定められた仕様です。
つまりEdgeは、最新のDOM仕様をサポートしていることになります。

そこで上記のW3CのHTMLCollectionの仕様を確認しますと、以下のように定義されていました。

interface HTMLCollection {
  readonly attribute unsigned long length;
  getter Element? item(unsigned long index);
  getter Element? namedItem(DOMString name);
};

なんと、もともとHTMLCollectionはイテレーブルと定義されていないようです。

念のためにW3Cでイテレーブルオブジェクトであると定義されているNodeListに対して、for-ofステートメントが使用できるか確認してみましょう。
(childNodesプロパティがNodeListオブジェクトを返します)

<script>
for (let node of document.body.childNodes) {
    console.log(“node.type = ” + node.nodeType)
    console.log(node)
}
</script>

上記のコードは、Microsoft Edgeでも以下のように問題なく動作することが確認できました。

どうやらHTMLCollectionがイテレーブルでない理由は、Microsoftが厳密にW3Cの仕様を守っていることが原因のようです。

MicrosoftはIE8以降、W3Cが定める仕様に積極的に準拠しています。
(主要ブラウザの開発動向とWeb標準準拠)

ただ仕様というのは最低限であり、素敵な機能がその横にあったとしても誰も問題にしないでしょう。

木曜日担当
yoshimoto

参考

Element.getElementsBy* が HTMLCollection を返すようになりました

W3C DOM4

DOM HTMLCollection




アプリ関連ニュース

お問い合わせはこちら

お問い合わせ・ご相談はお電話、またはお問い合わせフォームよりお受け付けいたしております。

tel. 06-6454-8833(平日 10:00~17:00)

お問い合わせフォーム