MENU

JavaScript用語解説配列・連想配列

【JavaScript】 アレイライク・配列風・配列のようなオブジェクトとは

更新日:2021/06/24

 

JavaScriptには言語仕様上『array-like object』というものがある。

 

アレイライクオブジェクト、または配列風オブジェクト、または配列のようなオブジェクトなどに日本語訳されています。

 

つまり、配列に似ているけれど配列ではないオブジェクトですね。

 

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

 

アレイライクなオブジェクトについては、ECMAScriptで定義されているので、そちらを参照してみる。

 

本来なら英語のオリジナルページを紹介するべきだが、日本語訳したのでそちらから抜粋します。

 

配列のようなオブジェクト(array-like object)とは、この操作で突然の完了で終了せずに、整数を返すオブジェクトです。

https://ecmascript2020言語仕様.com/abstract-operations/#h-lengthofarraylike

 

この操作とは、次のアルゴリズムを指しています。

 

  1. Assert: Type(obj)はObject型
  2. ? ToLength(? Get( obj, "length") ) の結果を返す

 

この処理は、lengthプロパティから値を取得しています。

 

この処理をおこなってエラーが出ない、つまりlengthプロパティがあれば、アレイライクなオブジェクトというわけです。

 

ただlengthプロパティがなくても、0と判断されてエラーにはなりません。
lengthプロパティが数字と判断できる文字列ならその数値、判断できないなら0です。
例外がスローされるのは、プロパティ値がSymbol型とBigInt型の時です。

 

それ以外はエラーにならないので、ほとんどのオブジェクトはアレイライクと言えます。

 

しかし、それでは運用として使いにくいです。
lengthプロパティを持つオブジェクトをアレイライクなオブジェクトと呼ぶのが無難かもしれません。

 

また、次のような文もあります。

 

通常、配列のようなオブジェクトには、整数のインデックス名を持ついくつかのプロパティもあります。 ただし、これはこの定義の要件ではありません。

 

整数インデックスの存在は、アレイライクかどうかには関係ないと明言していますね。

 

メソッドはlengthプロパティのみ参照

 

Array.fromというメソッドは、第一引数にアレイライクなオブジェクトを指定できます。

 

 

アルゴリズムの流れを要約してみます。

 

 

Array.from ( items [ , mapfn [ , thisArg ] ] )

 

  1. itemsがイテレーターの場合
    1. Arrayオブジェクトを作成
    2. 以下を繰り返す
      1. イテレーターから値を得る
      2. 終了ならArrayオブジェクトを返す(アルゴリズム終了)
      3. mapfnが関数なら、mapfnにイテレーターの値を渡し結果を得る
      4. mapfnが関数でないなら、イテレーターの値を結果とする
      5. Arrayオブジェクトに結果を追加

  2. itemsがイテレーターでない場合(アレイライクオブジェクトと想定)
    1. itemsオブジェクトのlengthプロパティ値を得る
    2. Arrayオブジェクトを作成
    3. カウンターkを用意し、0をセットする
    4. カウンターkがlengthプロパティ値未満の間、以下を繰り返す
      1. itemsオブジェクトのカウンターk値と同じ名前のプロパティから値を得る(プロパティがなければundefined)
      2. mapfnが関数なら、値を渡し結果を得る
      3. mapfnが関数でないなら、値を結果とする
      4. Arrayオブジェクトに値を追加
      5. カウンターkに1を加算
    5. Arrayオブジェクトを返す(アルゴリズム終了)

 

 

実際のアルゴリズムはもう少し複雑ですが、わかりやすいように切り詰めています。

 

このアルゴリズムでは、第一引数itemsイテレーターか、イテレーターではないかだけチェックしています。

 

そしてイテレーターではないなら、lengthプロパティを取得します。
lengthプロパティが存在しなかったり、数値でないとき一部を除いて0になります。

 

次に0からlengthプロパティ-1までカウントアップしていき、カウントに対応するitemsのプロパティから値を得ます。
対応するプロパティが無いときは、undefinedです。

 

次に第二引数mapfnが関数なら値を渡して結果を得ます。
このとき第三引数があるなら、this値としてmapfnに渡します。
mapfnが関数でないなら、値がそのまま結果として使用されます。

 

次に、新規作成されたArrayオブジェクトに結果を追加して、次のカウンターを処理します。

 

 

この一連の流れを見ると、lengthプロパティの値だけが重要なのがわかりますね。

 

 

では他のアレイライクなオブジェクトを要求するメソッドや関数はどうでしょうか?

 

そもそも、アレイライクなオブジェクトの定義要件は、lengthプロパティに係ることだけです。
インデックスに相当するプロパティの有無は要件ではありません。

 

そのため、オブジェクト内にインデックスに相当するプロパティがないことを考慮したアルゴリズムを組む必要があります。

 

すると必然的に、Array.fromと同じような扱いになります。

 

JavaScriptでは存在しないプロパティを参照するとundefined値が返ります。
そのため、undefinedを許容できるならインデックスの存在の有無を考慮する必要がないともいえます。

Arrayオブジェクトとアレイライクなオブジェクトの違い

 

Arrayオブジェクトはlengthプロパティを持っています。
そのため、Arrayオブジェクトはアレイライクなオブジェクトです。

 

前項のArray.fromでも、Arrayオブジェクトはアレイライクなオブジェクトとして扱われています。

 

しかしプログラムコード上ではArrayオブジェクトと、その他のアレイライクオブジェクトは、別のものとして扱われます。

 

■そもそもArrayオブジェクトとは?

 

Arrayオブジェクトは、エキゾチックなオブジェクトの一つで、配列としての機能を持ったオブジェクトです。

 

配列を処理するメソッドを持っているのはもちろんですが、それとは別に、要素の追加や削除などでlengthプロパティが変化する機能が備わっています。

 

その反対に、lengthプロパティを変更すると、既存要素の数が増減するという機能もあります。

 

 

ブラウザ上で動作させることを目的としたJavaScriptコードでよく話題になるのが、DOMのgetElementsByClassNameメソッドです。

 

このメソッドの使用目的は、対象となる複数のDOM要素を取得して、全ての要素に個別に処理をおこないたいというものが考えられます。

 

そこで候補に挙がるのがforEachメソッドです。

 

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

 


const elements = document.getElementsByClassName( className );

elements.forEach( e=>console.log( e ) );
  // Uncaught TypeError: elements.forEach is not a function

 

しかし、エラーが出てしまいました。

 

どうしてでしょうか?

 

実はgetElementsByClassNameメソッドは、Arrayオブジェクトでななくて、HTMLCollectionオブジェクトを返しています。
HTMLCollectionオブジェクトはlengthプロパティを持っているので、アレイライクなオブジェクトです。

 

しかしこのオブジェクトにはforEachメソッドが定義されていないので、上記のコードでエラーになってしまったのです。

 

オブジェクトがArrayオブジェクトではないので、forEachが使用できないという表現をすることがあります。
しかしforEachが使用できないのとArrayオブジェクトは関係ありません。
オブジェクトにforEachが定義されているかいないかの違いだけです。

 

APIを含めて組み込みオブジェクトのメソッドには、アレイライクなオブジェクトを返すものがあります。
このとき、プログラマーがArrayオブジェクトだと勘違いしていることがよくあります。

 

バグの原因にもなるので、何が返ってきているのか確認が必要です。

 

 

 

けーちゃんおススメ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


    ■このページのタイトル


    ■リンクタグ


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