MENU

JavaScript配列・連想配列関数・メソッド

【JavaScript】 Array.fromの使い方を理解する

更新日:2021/06/24

 

JavaScriptのArray.fromは、使いこなすと便利なメソッドです。
しかし少しわかりにくい面があると思います。

 

そこで今回は、Array.fromについて少し噛み砕いて解説します。

 

配列から新しい配列を生成

 

Array.fromは、配列の要素を一つずつコールバック関数に渡して、コールバック関数の戻り値から新しい配列を作成します。

 

例えば次のコードは、配列 [ 1 , 2 , 3 ] の要素を順番に、コールバック関数(2番目の引数)に渡して、その結果を新しい配列に格納して、返しています。

 


const array = Array.from( [ 1 , 2 , 3 ] , e => e * 2 );
console.log( array );  //  [ 2, 4, 6 ]

 

これは、次のようなArrayオブジェクトのmapメソッドでも同じ結果になります。

 


console.log( [ 1 , 2 , 3 ].map(  e => e * 2 ) );  //  [ 2, 4, 6 ]

 

配列の実体を操作するという意味では、mapメソッドの方が分かりやすいです。

 

しかし、Array.fromはアレイライク(配列のような)オブジェクトや、反復可能オブジェクトも処理の対象にできます。

 

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

 


const arrayLike = { length:3 , 0 : 1 , 1 : 2 , 2 : 3 };

const array = Array.from( arrayLike , e => e * 2 );
console.log( array );  //  [ 2, 4, 6 ]

 

アレイライクオブジェクトは、インデックスプロパティがなくても問題ありません。
そのため、次のように要素数だけを指定することも可能です。

 


const arrayLike = { length:3 };

const array = Array.from( arrayLike , e => 100 );
console.log( array );  //  [ 100, 100, 100 ]

 

上のコードで、引数eとして渡されるのはundefinedです。
そのため、関数内では引数を使用していません。

 

  1. 特定の要素数の配列を作成したい。
  2. 各要素に何らかの処理を加えたい。

 

この両方の目的に、上のコードが利用できます。

コールバック関数の引数

 

Array.fromの2番目の引数は、コールバック関数です。

 

コールバック関数は、次のような2つの引数を受け取ります。

 

第一引数: 要素値
第二引数: 要素のインデックス

 

Arrayオブジェクトのmapメソッドは、第三引数として処理中の配列を受け取ります。

 

コールバック関数の例

 


const array = Array.from( [ 1 , 2 , 3 ] ,
            function( e , index ) { return e * index; } 
        );

console.log( array ); // [ 0, 2, 6 ]

 

コールバック関数の例(アロー関数)

 


const array = Array.from( [ 1 , 2 , 3 ] ,
            ( e , index ) => e * index
        );

console.log( array ); // [ 0, 2, 6 ]

第一引数のみの動作

 

第一引数のみを指定してArray.fromを実行すると、要素の値をそのまま格納した配列が作成されます。

 


const array = Array.from( [ 1 , 2 , 3 ] );
console.log( array );  //  [ 1 , 2 , 3 ]

 

作成された配列は、元の配列とは別のものです。
そのため、コピー目的で使用されます。

 

またアレイライクオブジェクトを配列に変換する目的でも使用できます。

 

次のコードは、DOMのgetElementsByClassNameで取得したHTMLCollection(アレイライクなオブジェクト)を配列に変換しています。

 

 

HTMLCollectionを配列に変換

 


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

const elementsArray = Array.from( elements ) ;

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

 

このコードのelementsオブジェクト(HTMLCollection)は、次のようなプロパティを持っています。

 

elements{

     0: 要素1
     1: 要素2
     2: 要素3
       ・・・
     length : 要素数
}

 

これがそのまま配列に置き換わったイメージです。

 

アレイライクなオブジェクトに整数インデックスがない場合は、undefinedがセットされます。

 

次のようにlengthプロパティのみを指定すると、undefinedを要素に持つ配列が作成されます。

 


const arrayLike = { length:3 };
 
const array = Array.from( arrayLike );
console.log( array );  //  [ undefined, undefined, undefined ]

Array.fromとプリミティブ値

 

第一引数にUndefinedまたはNullを指定すると、TypeError例外がスローされます。

 

それ以外のプリミティブ値は、対応するオブジェクトに変換されます。

 

しかし、変換されたオブジェクトのほとんどは、lengthプロパティを持っていません。

 

そのため、要素数0の配列が生成されます。

 


console.log( Array.from( 1 ) ); // [ ]
console.log( Array.from( false ) ); // [ ]
console.log( Array.from( Symbol() ) ); // [ ]

 

ただし、Stringオブジェクトはlengthプロパティを持っています。

 

具体的には次のように、文字ごとに分割した数値プロパティと、文字数がセットされたlengthプロパティです。

 


console.log( new String( "abc" ) );
    // { 0: "a" , 1: "b" , 2: "c" , length: 3 }

 

これは典型的なアレイライクオブジェクトのため、Array.fromに文字列を渡すと、文字ごとに分割した配列が生成されます。

 


console.log( Array.from( "abc" ) ); // [ "a", "b", "c" ]
console.log( Array.from( "あいうえお" ) ); // [ "あ", "い", "う", "え", "お" ]

 

ここで、Stringオブジェクトについて問題が浮上してきます。

 

JavaScriptで使用している文字コードは、2つの要素で一つの文字を表しているものがあります。

 

 

例えば、次のような絵文字です。

 

"🙁🙂"

 

これをStringオブジェクトに変更してみます。

 


console.log( new String( "🙁🙂" ) );
// { 0: "\ud83d", 1: "\ude41" , 2: "\ud83d" , 3: "\ude42" , length: 4 }

 

2文字のはずが、4つに分割されてしまいました。

 

ということは、Array.fromを実行すると、次のような配列が生成されるはずです。

 

["\ud83d", "\ude41" , "\ud83d" , "\ude42" ]

 

実際にやってみます。

 


console.log( Array.from( "🙁🙂" ) );  //  [ "🙁", "🙂" ]

 

文字単位で分割されました。

 

なぜでしょうか。

 

実はStringオブジェクトはイテレーターが実装されていて、このイテレーターは文字単位で値を取得できます。

 


const iterator = "ab🙁🙂"[Symbol.iterator]();
let iteratorValue = iterator.next();
while (!iteratorValue.done) {
    console.log( iteratorValue.value );
               // 1回目: a
               // 2回目: b
               // 3回目: 🙁
               // 4回目: 🙂
    iteratorValue = iterator.next();
}

 

【JavaScript】 アレイライク・配列風・配列のようなオブジェクトとはで触れていますが、Array.fromは、オブジェクトにイテレーターが実装されている場合は、イテレーターから値を取得します。

 

そのため、イテレーターから取得した値で配列が作成されたのです。

 

Array.fromとthis値

 

Array.fromの3つめの引数は、コールバック関数に渡すthis値を指定します。
指定しない場合は、this値にundefinedがセットされます。

 

具体的な例を見ていきましょう。

 

 


const array = Array.from( [ 1 , 2 , 3 ] ,
    function(e){ return e * this.num; } ,
    { num:100 }
);

console.log(  array ); // [ 100, 200, 300 ]

 

3番目の引数で、numプロパティを持つオブジェクトを指定しています。
このプロパティは、コールバック関数内で this.num として参照できます。

 

ここでの注意点は、アロー関数が使えないということです。

 


const array = Array.from( [ 1 , 2 , 3 ] ,
    e => e * this.num ,
    { num:100 }
);
console.log(  array ); // [ NaN, NaN, NaN ]

 

アロー関数はthis値を持っていません。
そのため外部のthisの影響を受けます。

 

今回は、this.num が参照できずundefinedだったために、e * this.num の結果が NaN になりました。

 

3番目の引数でthis値を指定するなら、アロー関数の使用を避けてください。

 

アロー関数については、次の記事を読んでみてください。
【JavaScript】 アロー関数は何者!?かっこいいだけじゃない!

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


    ■このページのタイトル


    ■リンクタグ


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