MENU

JavaScriptDOM配列・連想配列

【JavaScript】 getElementsByClassNameでforEachがエラーな理由と対処方法

更新日:2021/06/24

 

JavaScriptでDOM操作をおこなっているとgetElementsByClassNameメソッドで取得した要素をforEachで処理したいときがあります。
しかし実際にコードを作成して実行するとエラーになってしまいます。

 

ここではその理由と、対処方法についてお伝えします。

 

エラーの内容

 

getElementsByClassNameで取得した配列をforEachで処理してみる。

 

やってしまいがちな間違いコード

 


const elements = document.getElementsByClassName( "classname" );

elements.forEach( e=>console.log( e ) );

 

Uncaught TypeError: elements.forEach is not a function

 

というエラーが出てしまった。

HTMLCollectionはアレイライクなオブジェクト

 

DOMのgetElementsByClassNameメソッドは、HTMLCollectionというオブジェクトを返します。

 

このオブジェクトは配列、つまりArrayオブジェクトと混同されることが多いですが、実際はアレイライクなオブジェクトに分類されます。

 

アレイライクなオブジェクトについては、次の記事を読んでみてください。
【JavaScript】 アレイライク・配列風・配列のようなオブジェクトとは

 

forEachメソッドを実行するには、オブジェクトにforEachメソッドが定義(実装)されている必要があります。

 

HTMLCollectionには定義されいないため、先ほどのコードはエラーになってしまったのです。

 

elements.forEach は undefined と評価されます。
undefinedは関数ではないので、is not a function(関数ではない)というエラーが表示されたのです。

対処法

 

対処法いくつか挙げてみます。

 

1:一番素直(おススメ)な対処法

 

おススメコード

 


const elements = document.getElementsByClassName( "classname" );

for( let i = 0 ; i < elements.length ; i ++ ) {
    console.log( elements[i] );
}

 

JavaScriptの中級者レベルになると、forループかっこ悪いと感じる人が出てきますが、効率的なこれが一番です。

 

2:Array.fromを使った対処法

 

例として挙げられていることが多いけれど、ムダに感じるコードです。

 

Array.fromを使った対処法

 


const elements = document.getElementsByClassName( "classname" );

const elementsArray = Array.from( elements ) ;

elementsArray.forEach( e=>console.log( e ) );

 

Array.fromは、アレイライクなオブジェクトをArrayオブジェクトに変換することも可能なメソッドです。

 

Array.fromについては、こちらを参考にしてみてください。
【JavaScript】 Array.fromの使い方を理解する

 

Arrayオブジェクトに変換後は、forEachメソッドが使用できます。

 

しかし、forEachメソッドを使用したいという理由だけで、Array.fromを実行するのはムダですね。

 

3:Array.prototype.forEachを使った対処法

 

次は僕の中では無理やり感満載なコードです。

 

Array.prototype.forEachを使った対処法

 


const elements = document.getElementsByClassName( "aaa" );

Array.prototype.forEach.call( elements , e => console.log( e ) );

 

ArrayオブジェクトのforEachメソッドの実体は、Array.prototype.forEachです。

 

この実体に対して、this値を変更するcallメソッドを実行しています。

 

これにより、HTMLCollectionを配列に見立てて処理できます。

 

 

ただしこれは、Array.prototype.forEachがアレイライクなオブジェクトでも動作するように設計されているからこそ可能な方法です。

 

おそらくないと思いますが、今後のバージョンアップでArrayオブジェクトのみを受け付けるようになったら、動作しなくなります。

 

この意味からすると、「今はこんな方法もありますよ」というとても消極的な例示にとどめておくべきかもしれません。

 

4:なにがなんでもgetElementsByClassNameでforEachしたい

 

getElementsByClassNameで取得した値にそのままforEachしたいときは、次のようにHTMLCollectionにforEachメソッドを組み込みます。

 

getElementsByClassNameでforEach

 


HTMLCollection.prototype.forEach = function ( callbackfn  , thisArg = undefined ){
    for( let i = 0 ; i < this.length ; i ++ )
        callbackfn.call( thisArg , this[i] , i , this )
};

const elements = document.getElementsByClassName( "aaa" );
elements.forEach ( e=>console.log( e ) );

 

forEachで定義している関数は、引数などのチェックをおこなっていません。
いろいろ面倒なので、次のようにArray.prototype.forEachをセットしてしまうのでもいいかもしれません。

 

HTMLCollection.prototype.forEach = Array.prototype.forEach;

 

APIも含めて組み込みオブジェクトにプログラムコードでプロパティを追加するのは推奨されていないので、僕としてはおススメしません。

 

ただ、このような方法もあるという知識は持っている方がいいので、紹介しています。

けーちゃんおススメJavaScript入門書

  • スラスラ読める JavaScript ふりがなプログラミング
  • プログラム未経験者がJavaScript始めるならコレ!
    コードを掲載して自分で理解しろという投げっぱなしな入門書とは異なり、コードに一つ一つどんなことをやっているかをふりがなという形式で解説しています。
    それでいてJavaScriptの基礎と応用を学べる良書です。
  • これからWebをはじめる人のHTML&CSS、JavaScriptのきほんのきほん
  • JavaScriptの機能を実践で活かすにはHTMLやCSSの知識が不可欠です。
    しかしそれらの知識があることが前提として書かれている書籍が多い中、この本は総合的な知識を身に着けることができます。
    HTMLやCSSの知識も不安な方には、ぴったりの一冊です
  •  

    入門書の役割は、自分のやりたいことをネットで調べることができるようになるための、基礎的な知識の獲得です。
    まずはこれらの本でしっかりと基礎知識を身につけましょう。
    そしてもっと高度なことや専門的なことはネットで調べ、情報が足りないと感じたら書籍を購入してください。


    期間限定情報:
    7/16から7/18は63時間のビッグセール!
    欲しかったアレが安く手に入るチャンスです
    忘れずにチェックしてください!
    僕は以前のタイムセール祭りで4Kモニタが買ったけど、それより安かったらどうしよう・・・

    さらにお得なポイントアップキャンペーンも同時開催!

    記事の内容について

     

    こんにちはけーちゃんです。
    説明するのって難しいですね。


    「なんか言ってることおかしくない?」
    たぶん、こんなご意見あると思います。

    裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。

    そんなときは、ご意見もらえたら嬉しいです。

    ご意見はこちら。
    https://note.affi-sapo-sv.com/info.php

    【お願い】

    お願い

    ■このページのURL


    ■このページのタイトル


    ■リンクタグ


    ※リンクして頂いた方でご希望者には貴サイトの紹介記事を作成してリンクを設置します。
    サイト上部の問い合わせよりご連絡ください。
    ただしサイトのジャンルによっては、お断りさせていただくことがあります。