🌊

JavaScript:a[1] = 1な配列aでa.map((_, i) => a[i + 1])[0]が1じゃなかった。なぜ?

2024/07/01に公開

答え: aが疎配列だったから

JavaScriptには疎配列という概念があります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Indexed_collections#疎配列
これは「空のスロット」を格納した配列のことで、具体的には次のように書くと疎配列になります。

const a = [, 1];
// a[0] = 空のスロット, a[1] = 1

この「空のスロット」はnullでもundefinedでもありません。そして、
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array#配列メソッドと空のスロット
には、

疎配列において空のスロットは、配列のメソッド間で一貫性のない動作をします。

とあります。
そしてmapに関しては、次のような記述があります。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map#疎配列に対する_map_の使用

疎配列は map() の後も疎配列のままです。空のスロットのインデックスは返された配列においても空のままであり、コールバック関数が呼び出されることはありません。

重要なのでもう一度引用しておきます

空のスロットのインデックスは返された配列においても空のままであり、コールバック関数が呼び出されることはありません。

つまりこういうことになります

const a = [, 1];
const b = a.map((_, i) => a[i + 1]);
// b[0]について、a[0]が空のスロットなので
// 「空のスロットのインデックスは返された配列においても空のままであり、コールバック関数が呼び出されることはない」
// という挙動によりb[0]は空のスロット
// ちなみにb[1]は普通にundefined

以上

Discussion