まあ、分かってしまえばなんということはないんですが、結構面食らいますね。
This sure isn't what I would have expected. pic.twitter.com/wNQ0CkycUn
— Andy Hall (@fenomas) January 23, 2018
MDNにはちゃんと書いてありました。
Array.prototype.map() - JavaScript | MDN
(callback) is not called for missing elements of the array (...) Due to the algorithm defined in the specification if the array which map was called upon is sparse, resulting array will also be sparse keeping same indices blank.
つまり、空要素に対してはcallbackは呼ばれず、配列のsparse状態(空要素があるという情報)も維持されるということなので、仕様どおりの挙動ではあります。
この「空要素(missing element)」はちょっと分かりにくいんですが、要素の置き場所だけが確保されていて実際には何の値も入っていないという要素です。式として評価すると undefined
になります。こんなふうに:
console.log( (new Array(2))[0] === undefined ); // true
in
演算子だと空要素かどうかを調べられます。
console.log( 0 in (new Array(2) )); // false console.log( 0 in [undefined] ); // true
そして Array.from(iterable)
や [...iterable]
はこのsparse状態は保たず、undefined
に変換してしまうようです。
console.log(new Array(2)); // [ <2 empty items> ] console.log([...new Array(2)]); // [ undefined, undefined ] console.log(Array.from(new Array(2))); // [ undefined, undefined ]
面白いですね!