假設(shè)我們有下面代碼
let arr = Array(5).map(item => {
return item = 4
}
console.log(arr)
我們預(yù)期輸出的是[4,4,4,4]
, 然而輸出的是[undefined, undefined, undefined, undefined]
那么好吧, 我們console.log(Array(5))
試試結(jié)果, 結(jié)果是[undefined, undefined, undefined, undefined]
那么, 按上面的情況來(lái)看,我們對(duì)[undefined, undefined, undefined, undefined]
使用上面的map方法, 是不是應(yīng)該也得到相同的結(jié)果呢?
let arr = [undefined,undefined,undefined,undefined,undefined].map(item => {
return item = 4
})
console.log(arr)
然后結(jié)果竟然是[4,4,4,4]
!!!, 這就尼瑪有點(diǎn)坑了异逐。
為什么會(huì)出現(xiàn)上面這種現(xiàn)象呢, 這就要引入一個(gè)概念 --- 數(shù)組空位
所謂數(shù)組空位, 就是數(shù)組的某個(gè)位置沒有值, 如下面的幾種方式, 都會(huì)產(chǎn)生數(shù)組空位, 用map()
forEach()
filter()
等方法遍歷數(shù)組時(shí), 當(dāng)遇到數(shù)組空位, 方法都會(huì)跳過(guò)此位置, 直接遍歷下一個(gè)位置.
// 產(chǎn)生5個(gè)數(shù)組空位的數(shù)組
let arr1 = Array(5)
//同上
let arr2 = [,,,,,]
//產(chǎn)生10個(gè)數(shù)組空位的數(shù)組
let arr3 = []
arr3.length = 10
//數(shù)組a[3]-a[9]都是數(shù)組空位
let arr4 = [1,2,3]
arr4[10] = 5
//數(shù)組arr[2]產(chǎn)生數(shù)組空位
let arr5 = [1,2,3,4,5]
delete arr[2]
我們?cè)儆胕n操作來(lái)測(cè)試一下數(shù)組空位
0 in [undefined, undefined, undefined] // true
0 in [, , ,] // false
上面代碼說(shuō)明演训,第一個(gè)數(shù)組的 0 號(hào)位置是有值的,第二個(gè)數(shù)組的 0 號(hào)位置沒有值。
宗上所述, 給數(shù)組某一項(xiàng)的值傳為undefined
, 僅表示數(shù)組該項(xiàng)的值為空, 因?yàn)?code>undefined本身也是一種類型的值, 本質(zhì)上等同于我們給數(shù)組傳了一個(gè)undefined
值, 也就說(shuō), 當(dāng)我們給數(shù)組的某個(gè)位置傳入undefined
, 并不會(huì)產(chǎn)生數(shù)組空位, 所以跟數(shù)組空位得到的結(jié)果不同字管。
但是瀏覽器有一個(gè)坑, 當(dāng)我們console.log()
一個(gè)數(shù)組時(shí), 數(shù)組空位會(huì)顯示undefined, 這樣就很容易讓我們和給數(shù)組傳undefined值混淆, 必須下面這種情況
console.log([undefined, undefined, undefined, undefined]) // 輸出顯示[undefined, undefined, undefined, undefined]
console.log(Array(4)) //輸出還是顯示[undefined, undefined, undefined, undefined]
上面的代碼中, 無(wú)論我們輸出數(shù)組空位還是undefined, 最終瀏覽器顯示的都是undefined, 所以才造成了上面的坑晤愧。
ES6中的數(shù)組空位
我們?cè)谏厦嬷v了, ES5 對(duì)空位的處理绍昂,已經(jīng)很不一致了羔飞,大多數(shù)情況下會(huì)忽略空位。
比如:
forEach() , filter() , every() 和some()都會(huì)跳過(guò)空位挎袜。
map()會(huì)跳過(guò)空位顽聂,但會(huì)保留這個(gè)值
join()和toString()會(huì)將空位視為undefined肥惭,而undefined和null會(huì)被處理成空字符串。
// forEach 方法
[,'a'].forEach((x,i) => console.log(i)); // 1
// filter 方法
['a',,'b'].filter(x => true) // ['a','b']
// every 方法
[,'a'].every(x => x==='a') // true
// some 方法
[,'a'].some(x => x !== 'a') // false
// map 方法
[,'a'].map(x => 1) // [,1]
// join 方法
['x',,undefined,null].join('!') // "x!!!"
// toString 方法
['x',,undefined,null].toString() // "x,,,"
ES6 新增的數(shù)組方法則是會(huì)將數(shù)組空位轉(zhuǎn)換為undefined紊搪。
Array.from
和展開運(yùn)算符(...)
方法會(huì)將數(shù)組的空位蜜葱,轉(zhuǎn)為undefined,
Array.from([1,,2])
// [ 1, undefined, 2 ]
[...[1,,2]]
// [ 1, undefined, 2]
copyWithin()會(huì)連空位一起拷貝耀石。
[1,,,2].copyWithin(2,0) // [1,,,2]
fill()會(huì)將空位視為正常的數(shù)組位置牵囤。
Array(3).fill(1) // [1,1,1]
for...of循環(huán)也會(huì)遍歷空位。
let arr = [, ,]
for (let i of arr) {
console.log(1);
}
// 1
// 1
entries()滞伟、keys()揭鳞、values()、find()和findIndex()會(huì)將空位處理成undefined梆奈。
// entries()
[...[,'a'].entries()] // [[0,undefined], [1,"a"]]
// keys()
[...[,'a'].keys()] // [0,1]
// values()
[...[,'a'].values()] // [undefined,"a"]
// find()
[,'a'].find(x => true) // undefined
// findIndex()
[,'a'].findIndex(x => true) // 0
從上面的各種例子我們可以看到, 不同的數(shù)組方法, 對(duì)數(shù)組空位的處理非常的不統(tǒng)一, 因此為了避免采坑, 我們?cè)诰幊虝r(shí), 需要避免出現(xiàn)數(shù)組空位野崇。