跳至內容
Astera Technology

陣列空位和 undefined,迭代時未必一樣

陣列長度以外,還要核對索引是否真的有項目。

下載完整個案資料及參考答案 ↓

先追這段程式

[1,,undefined] 長度是 3,中間留了空位,最後則明確存 undefined。記下 map 實際呼叫了哪些索引。

完整原始程式
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}));
確實的 console 輸出
{"length":3,"hasMiddle":false,"hasLast":true,"visited":[{"index":0,"type":"number"},{"index":2,"type":"undefined"}]}
值與執行位置
Index屬性存在回呼結果
0truenumber
1false略過
2trueundefined

結果為何如此

map 先查索引屬性是否存在,包括繼承項。本例新建普通陣列沒有繼承數字鍵,索引 1 不存在,索引 2 存在。JSON 陣列中空位和 undefined 都可能顯示 null,不能靠它判斷是否有項目。

比較另一種寫法

相同 JSON 文字可能藏着不同屬性狀態:空位和明確 undefined,在這裡都變 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}

試清邊界

Array.from 把空位變成 undefined 項目後,map 會呼叫幾次?

查看參考答案

三次,索引 0、1、2 都會跑。中間已有項目,值雖是 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]}

原始例子檔案