HTMLCollectionがiterableかどうかの検証
- 2018年6月28日
- 技術情報
突然ですが、Chrome、Safari、Firefox、Microsoft Edgeの中で
以下のコードが動かないものが一つだけあります。
<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> |
上記のコードは、Microsoft Edgeでも以下のように問題なく動作することが確認できました。
どうやらHTMLCollectionがイテレーブルでない理由は、Microsoftが厳密にW3Cの仕様を守っていることが原因のようです。
MicrosoftはIE8以降、W3Cが定める仕様に積極的に準拠しています。
(主要ブラウザの開発動向とWeb標準準拠)
ただ仕様というのは最低限であり、素敵な機能がその横にあったとしても誰も問題にしないでしょう。
木曜日担当
yoshimoto
参考
Element.getElementsBy* が HTMLCollection を返すようになりました
yoshimoto at 2018年06月28日 10:00:15