JavaScriptで、配列を作るのに使えるArray.fromというメソッドがありますが、これにはいろんな使い方があります。
引数に指定できるオブジェクト
Array.from(obj)とできるオブジェクトには、大きく分けて2種類あります。
- iterable
- 配列のようなオブジェクト
iterable
最初のiterableとは、[Symbol.iterator]メソッドを持つものです(for-ofに使えるもの、と言っても同じです)。配列そのものやMap、Setといったデータ構造、document.querySelectorAll()で得られるNodeList、さらには文字列もiterableなので、Array.fromに投げ込むことができます。
配列をArray.fromで処理した場合、配列がコピーされる効果以外に、疎な配列をundefinedで埋める、という動作も行います。Array(10)で長さだけ決めた配列は、要素が空となってforEachが1回も回らない、みたいなことになりますが、Array.from(Array(10))として作成された配列は全部undefinedで埋まり、forEachも各要素ごとに実行されるようになります。
ただし、この機能性については[...obj]と書いても同様に動くので、Array.fromを呼ぶまでもないかもしれません。
配列のようなオブジェクト
曖昧な表現のように見えて「配列のようなオブジェクト」はJavaScriptの技術用語となっていて、「非負整数のlengthプロパティを持つオブジェクト」を意味します。たとえば、jQueryの$()で生成されるオブジェクトもこの種のものです。
極端な話、lengthさえあればいいので、Array.from({length: 10})と書いても動作します({length: 10}[0]などはundefinedなので、undefinedが10個入った配列が出来上がります)1。こちらはスプレッド構文では動作しません。
第2引数に関数を渡す
さらに、Array.fromには第2引数として関数を渡すことができます。この場合、
- 引数:値、配列のインデックスの2つ
- 返り値:配列に入れたい値
のように実行されます。結果としてはArray.fromで得られた配列をmapするのと同じではあるのですが、いったん配列を作らなくて済むので効率的です。
-
Array.from(Array(10))のほうが文字数が短いですし、Arrayが2回現れるので圧縮をかける上ではさらに有利と思われます。 ↩