LINDORのAdvent Calendar(本物)の5日目を開けたところ。
配列とかおれおれAdvent Calendar2018 – 05日目

配列風オブジェクトから Array インスタンスを生成します。

const nodeList = document.querySelectorAll('.target');
const arr = Array.from(nodeList);
console.log(arr);

利用可能なのは以下の2種類です。

  • 配列風オブジェクト
  • 反復可能なオブジェクト

あと第2引数に関数を受け付けて、 map() みたいなマッピングが可能です。

配列風オブジェクト

length を持ってて [0], [1], [2], … で要素にアクセスできるやつ。

const arrayLike = {
  0: 11,
  1: 22,
  2: 33,
  length: 3,
};
const arr = Array.from(arrayLike);
console.log(arr); // => [ 11, 22, 33 ]

反復可能なオブジェクト

反復可能とは、ざっくり言うと for-of で使えるiterableなやつ。正確なところは別の記事に分けます。

配列

実は配列自体も反復可能なのです。特別扱いされているんじゃなくて、そういう共通処理が使える。

なおshallow copyなので、要素は同じです。

const arr0 = [
  { value: 11 },
  { value: 22 },
  { value: 33 },
];
const arr1 = Array.from(arr0);

console.log(arr0 === arr1); // => false
console.log(arr0[0] === arr1[0]); // => true

Map, Map

こいつらも反復可能なので使えます。

const set = new Set();
set.add(11);
set.add(22);
set.add(11); // 重複
set.add(33);
const arr = Array.from(set);
console.log(arr); // => [ 11, 22, 33 ]

文字列

配列風オブジェクトの範疇ですが、実は本当に反復可能なオブジェクトです。

const arr = Array.from('Hello World!');
console.log(arr);
// => [ 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!' ]

NodeList

DOMのやつ。反復可能です。

const els = document.querySelectorAll('.target');
const arr = Array.from(els);
console.log(arr);

HTMLCollection ?

document.links みたいなやつらもそうっぽい。

const els = document.getElementsByClassName('foo');
const arr = Array.from(els);
console.log(arr);

Chrome, Firefox, Edgeでは動いたんだけど、これどこの仕様かわからない……。

jQuery

ところでjQueryもiterableなんですね。私、知らなかったわ。

というわけで使えます。

マッピング

第2引数に関数を受け付けて、マッピングしながら作成できます。

const nodeList = document.querySelectorAll('input[type=text]');
const textList = Array.from(nodeList, (el) => el.value);
console.log(textList);

任意の数の配列を作る

MDNに載ってたやり方。配列風オブジェクトの応用でやれます。

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

new Array(3) ↓と違い、ちゃんと undefined が設定されていることに注目してください。

const arr = Array(3);
console.log(arr); // => [ <3 empty items> ]
console.log(arr.length); // => 3

マッピングと組み合わせて初期値を設定するのも良さそう。

const arr = Array.from({ length: 3 }, (_, i) => i);
console.log(arr); // => [ 0, 1, 2 ]

その他

継承

Array.of() ↓もそうだったんだけど、 Array.from() の方も継承したコンストラクターから利用かのうなよう設計されています。

おしまい

スプレッド構文 ... の方が楽な気がする。

これは反復可能であれば使えます。配列風はだめなので、今回の Array.from() で。

関連

参考