HTMLCollectionで配列メソッドを使う

document.getElementsByTagNameとかでDOMをいくつか引っ張ってきたりすると、HTMLCollectionオブジェクトが返ってきます。

var selects = document.getElementsByTagName("select");
// -> object HTMLCollections

このオブジェクト、配列っぽく動作するので忘れがちなんですが、本当は 配列ではない ので、例えばforEachみたいな便利メソッドが使えません。

selects.forEach(function(item) {
  // itemを使った処理
});
// -> error

しかし、配列のメソッドには便利なものが多く、また、使えないとメソッドチェインを使ったアレコレができないので、コンソールとかでデバッグしてるときに辛いです。(例えば特定の要素だけが欲しいとかなったときはfilterしますよね)

そこで、配列メソッドをなんとかして利用する方法を。

1. Array.prototypeを利用する

Array.prototype.forEach.call(selects, function(item) {
  // itemを利用した処理
}

2. なんとかして配列に変換する

var selects = Array.prototype.slice.call(selects);
// -> Arrayになった

selects.forEach(function(item) {
  // itemを利用した処理
});

Array.prototype.sliceは引数を省略すると全部をとってきてくれるので、これを利用してArrayへと変換してしまう方法です。メソッドチェインを使うと

Array.prototype.slice.call(selects).filter(function(item, index, all) { return item.hasAttribute("multiple"); }).forEach(function(item) { alert(item); });

みたいな感じでmultiple属性がついたセレクトボックスだけに特定の処理をする、というプログラムが一行で書けます。幸せですね。

参考