JavaScriptのArray.prototype.map()はとても便利なメソッドです。
これのお陰でfor文の出番はかなり減り、コードもスタイリッシュになりました。
なので皆さんも是非活用して欲しいと思っています。
そこで今回は、僕がうっかりミスしたarray.map()の落とし穴をご紹介したいと思います。
やりたかった事
const ary = new Array(3).map(() => "hogehoge");
一見すると
- 要素数3の配列を生成
- 生成された配列を元に
mapで各要素に"hogehoge"を格納 -
mapで生成された配列をaryに代入
というスタイリッシュな流れが思い浮かびます。
しかし、実際にはこれは上手く行きません。
console.log(ary); // [(empty), (empty), (empty)]
MDNを読んだら当たり前だった
map() メソッドは、与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。
(MDNから引用)
つまりどういう事だってばよ
new Array(n)で生成された配列は、中身が(empty)つまり空なのです。
MDNの説明で "すべての要素に対して呼び出し" と書いてある通り、要素が無いとそもそも呼び出されないのです。
配列リテラル[,,,]で生成された配列も同じく、各要素は空となります。
const ary1 = new Array(3); // [(empty), (empty), (empty)]
const ary2 = [,,,]; // [(empty), (empty), (empty)]
この2つはどちらも同じくmapしても呼び出されません。
どうすればいいの
要素に何らかの値が入っていれば呼び出されます。
const ary1 = [null, null, null].map(() => "hogehoge"); // ["hogehoge", "hogehoge", "hogehoge"]
const ary2 = [undefined, undefined, undefined].map(() => "hogehoge"); // ["hogehoge", "hogehoge", "hogehoge"]
const ary3 = ["", "", ""].map(() => "hogehoge"); // ["hogehoge", "hogehoge", "hogehoge"]
JavaScriptにおいてnullやundefinedはプリミティブです。
なので「nullやundefinedという**"値"**が入っている」といった意味になります。
つまりmapで呼び出される対象となる訳です。
おわりに
Array.prototype.map()を活用してより良いJavaScriptライフを!