當數組中存在空位時,遍曆數組需要選擇合適的方法,不同的方法可能返回不同的結果,有些方法會跳過空位,有些則會返回undefined。 ...
當數組中存在空位時,遍曆數組需要選擇合適的方法,不同的方法可能返回不同的結果。
示例數組:
const arr = [1, 2, , 3, 4];
數組空位不會影響數組長度,arr
的長度是 5。
for迴圈
最朴素的 for 迴圈會遍歷到數組的每一位,對於空位,訪問時返回 undefined。
for(let i=0; i<arr.length; i++){
console.log(arr[i]);
}
輸出:
1
2
undefined
4
5
forEach方法
forEach 方法會跳過空位,所以這裡只遍歷到了4個數。
arr.forEach(el=>{
console.log(el);
});
輸出:
1
2
4
5
for in 方法
for-of 和普通的 for迴圈結果是一樣的,這裡看 for-in 的結果。
for-in 遍曆數組對象的可枚舉屬性鍵,會跳過空位。
for(let key in arr){
console.log(arr[key]);
}
輸出:
1
2
4
5
數組的entries方法
數組的 entries 方法返回一個包含數組中每個索引的鍵值對的迭代器對象。當遇到空位時,對應的值讀取為 undefined。
for (let [key, value] of arr.entries()) {
console.log([key, value]);
}
輸出:
[ 0, 1 ]
[ 1, 2 ]
[ 2, undefined ]
[ 3, 4 ]
[ 4, 5 ]
思考:什麼時候會忽略空位?
根據上面4種簡單的情形,可以看到 forEach方法和for-in 迴圈會跳過空位,而其它則不會。
事實上,除了 forEach 方法,傳入一個回調函數遍曆數組的方法都會忽略空位,包括但不限於:map, filter, reduce, find。
而 for-in 迴圈之所以會忽略空位,是因為空洞對應的索引沒有被創建為可枚舉屬性,因此不會被 for-in 遍歷到。
數組作為一種對象,key 是數字索引,value 是數組元素。
同理,如果使用 Object.keys()
,Object.values()
,Object.entries()
遍曆數組對象,會發現空洞都會被忽略。
但是,數組原型上的.keys
,.values
,.entries
方法,是為數組特殊設計的,用這些方法遍曆數組,就不會跳過空位。
for-of 迴圈遍曆數組為什麼不會跳過空位?for-of 一個數組對象,會調用它的 [Symbol.iterator]
方法返回一個迭代器。而 Array.prototype.values
是 Array.prototype[Symbol.iterator]
的預設實現,於是 for-of 和.values
方法保持一致,都不會跳過空位。
對比總結
for
:不忽略for in
:忽略空位for of
:不忽略
這仨原理不一樣,只是因為長得像所以放一起。
for in
忽略空位是和下麵的對象方法一個道理。而
for of
不忽略空位和下麵數組的values
等方法是一個道理。
- 對象方法
Object.keys()
,Object.values()
,Object.entries()
:忽略空位 - 數組方法:
forEach
,map
,filter
,every
,reduce
等:忽略空位keys
,values
,entries
:不忽略空位