Trace the fixed program
The array [1,,undefined] has length 3. Compare its omitted middle slot with its explicit final undefined and record every map callback.
const values=[1,,undefined];const visited=[];
values.map((value,index)=>{visited.push({index,type:typeof value});return value;});
console.log(JSON.stringify({length:values.length,hasMiddle:1 in values,hasLast:2 in values,visited}));
{"length":3,"hasMiddle":false,"hasLast":true,"visited":[{"index":0,"type":"number"},{"index":2,"type":"undefined"}]}| Index | Property present | Callback observation |
|---|---|---|
| 0 | true | number |
| 1 | false | Skipped |
| 2 | true | undefined |
Explain the result
map checks whether each index property exists, including inherited properties, before calling the callback. This fresh ordinary array has no inherited numeric entries: index 1 is absent and index 2 is present. JSON can render both holes and undefined array entries as null, so it is not a presence test.
Test the alternative
The same JSON text can conceal different property presence. A hole and an explicit undefined both serialize here as null.
const hole=[,];const explicit=[undefined];console.log(JSON.stringify({holeJSON:JSON.stringify(hole),explicitJSON:JSON.stringify(explicit),holePresent:0 in hole,explicitPresent:0 in explicit}));
{"holeJSON":"[null]","explicitJSON":"[null]","holePresent":false,"explicitPresent":true}Work the boundary case
How many callbacks run after Array.from fills this array’s hole with undefined?
Show the worked answer
Three, at indexes 0, 1 and 2. The middle index is now present, even though its value is undefined.
const values=Array.from([1,,undefined]);const visited=[];values.map((value,index)=>{visited.push(index);return value;});
console.log(JSON.stringify({middlePresent:1 in values,middleType:typeof values[1],visited}));
{"middlePresent":true,"middleType":"undefined","visited":[0,1,2]}