1. 程式人生 > 實用技巧 >Js中陣列空位問題

Js中陣列空位問題

Js中陣列空位問題

JavaScript中陣列空位指的是陣列中的empty,其表示的是在該位置沒有任何值,而且empty是區別於undefined的,同樣empty也不屬於Js的任何資料型別,並且在JavaScript版本以及各種方法對於空位的處理也有不同,所以建議避免在陣列中出現空位。

描述

JavaScript的陣列是以稀疏陣列的形式存在的,所以當在某些位置沒有值時,就需要使用某個值去填充。當然對於稀疏陣列在各種瀏覽器中會存在優化的操作,例如在V8引擎中就存在快陣列與慢陣列的轉化,此外在V8中對於empty的描述是一個空物件的引用。在Js中使用Array構造器創建出的存在空位的問題,預設並不會以undefined

填充,而是以empty作為值,需要注意的是,空位並不是undefinedundefined表示的是沒有定義,但是本身undefined就是一個基本資料型別,是一個值,而是empty表示了該處沒有任何值,是一個完全為空的位置。

console.log([,,,]); // (3) [empty × 3]
console.log(new Array(3)); // (3) [empty × 3]
console.log([undefined, undefined, undefined]); // (3) [undefined, undefined, undefined]
console.log(0 in [undefined, undefined, undefined]); // true
console.log(0 in [,,,]); // false // in 是檢查索引 此處表示 0 位置是沒有值的

方法處理

ECMA262V5中對空位的處理就已經開始不一致了,在大多數情況下會忽略空位,例如forEach()for infilter()every()some()都會跳過空位,map()會跳過空位,但會保留這個值,join()toString()會將空位與undefined以及null處理成空字串。

// forEach 忽略空位
[1, , 2].forEach(v => console.log(v)); // 1 2

// for in 忽略空位
for(let key in [1, , 2]){ console.log(key); } // 0 2

// filter 忽略空位
console.log([1, , 2].filter(v => true)); // [1, 2]

// every 忽略空位
console.log([1, , 1].every(v => v === 1)); // true

// some 忽略空位
console.log([1, , 1].some(v => v !== 1)); // false

// map 遍歷時忽略空位 新陣列保留空位
console.log([1, , 1].map(v => 11)); // (3) [11, empty, 11]

// join 將空位與undefined以及null視為空字串
console.log([1, , 1, null, undefined].join("|")); // 1||1||

// toString 將空位與undefined以及null視為空字串
console.log([1, , 1, null, undefined].toString()); // 1,,1,,

ECMA262V6則是將空位轉為undefined,例如Array.form()方法會將陣列的空位轉為undefined,擴充套件運算子也會將空位轉為undefinedcopyWithin()會連同空位一起拷貝,for of迴圈也會遍歷空位並將值作為undefinedincludes()entries()keys()values()find()findIndex()等會將空位處理成undefined

// Array.form 將空位轉為undefined
console.log(Array.from([1, , 2])); // (3) [1, undefined, 2]

// ... 將空位轉為undefined
console.log([...[1, , 2]]); // (3) [1, undefined, 2]

// copyWithin 將空位一併拷貝
console.log([1, , 2].copyWithin()); // (3) [1, empty, 2]

// for of 遍歷空位並將值作為undefined
for(let key of [1, , 2]){ console.log(key); } // 1 undefined 2

// includes 將空位處理成undefined
console.log([, , ,].includes(undefined)); // true

// entries 將空位處理成undefined
console.log([...[1, , 2].entries()]); // [[0, 1], [1, undefined], [2, 2]]

// keys 會取出空位的索引
console.log([...[1, , 2].keys()]); // [0, 1, 2]

// values 將空位處理成undefined
console.log([...[1, , 2].values()]); // [1, undefined, 2]

// find 將空位處理成undefined
console.log([, , 1].find(v => true)); // undefined

// find 將空位處理成undefined
console.log([, , 1].findIndex(v => true)); // 0

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

https://www.zhihu.com/question/60919509
https://juejin.im/post/6844903917738786829
https://segmentfault.com/a/1190000004680060
https://xmoyking.github.io/2016/12/17/js-framework2/
https://juejin.im/post/6844904047934373896#heading-12
https://blog.csdn.net/qq_30100043/article/details/53308524
https://blog.csdn.net/weixin_43342105/article/details/108638001