JavaScript 中陣列的特殊性
- 每一項都可以儲存任意型別的資料,陣列大小可以動態調整,即可以隨著資料的新增自動增長以容納新資料
- 陣列中可能會存在空位
- 稀疏陣列
具有不連續索引的陣列,其 length 屬性值大於元素的個數。
- 密集陣列
具有連續索引的陣列,其 length 屬性值等於元素的個數。
在 JavaScript 中,陣列本質上也是物件,是物件的一種特殊形式。
陣列索引實際上和碰巧是整數名的物件屬性沒有什麼差別,不過陣列的實現是經過了優化的,通過陣列索引訪問陣列元素比訪問一般物件的屬性要快的多。
規定陣列索引的範圍是 0 ~ 4294967294 (2^32 - 2)
, 所有的索引都是屬性名, 但是隻有在這個範圍內的整數才是陣列索引,陣列索引會觸發陣列的特殊行為。
陣列的建立方式
陣列字面量
這是我們平時使用最多,最簡單的陣列建立方式。
const arr1 = []
複製程式碼
建構函式
利用建構函式建立陣列的時候,在只有一個引數的情況下,根據引數的型別不同,會返回不同的結果。
// 注:這種方式建立的陣列屬於稀疏陣列,每一項都是空位,下邊會具體介紹稀疏陣列。
// 請避免使用這樣的方式建立陣列。
const arr1 = Array(3) // [empty × 3]
const arr2 = Array(`3`) // ["3"]
複製程式碼
of() 方法
這是 ES6 中新增的方法,用來彌補建構函式的的缺陷。
不會根據引數的型別不同導致建立行為的不同。
const arr1 = Array.of(3) // [3]
const arr2 = Array.of(`3`) // [`3`]
複製程式碼
from() 方法
ES6 新增的方法,這個方法的主要用途就是將類陣列物件轉為陣列物件。
建立給定長度的陣列這個方法會很好用。
const arr1 = Array.from({length: 3}) // [undefined, undefined, undefined]
複製程式碼
稀疏陣列
稀疏陣列就是存在空位的陣列,這裡簡單介紹一下:
空位的檢測 in
空位是沒有任何值,可以用 in 運算子檢測。我們可以根據 in 字元來檢測陣列某一項是否是空位。
const a = [,,,] // [empty × 3]
0 in a // false
const b = [1,2,3]
0 in b //true
複製程式碼
造成稀疏陣列的操作
- delete 操作符
使用 delete 操作符可以將陣列項從陣列中刪除,陣列的長度並不會發生變化,而是會留下一個空位。
const b = [1,2,3]
delete b[0]
console.log(b) // [empty, 2, 3]
複製程式碼
- 建構函式
const a = Array(3)
console.log(a) // [empty × 3]
複製程式碼
- 在陣列字面量中省略值
[,,,] // [empty × 3]
複製程式碼
- 指定陣列索引大於陣列長度
const c = []
c[10] = 0;
console.log(c) // [empty × 10, 0]
複製程式碼
- 指定陣列長度大於當前陣列長度
const a = []
a.length = 10 // [empty × 10]
複製程式碼
我們在平時要儘量避免建立和使用稀疏陣列,因為在 ES6 之前的方法,對稀疏陣列的處理存在很多不統一的地方。
操作的不統一
ES5 對空位的處理,已經很不一致了,大多數情況下會忽略空位。
- forEach(), filter(), reduce(), every() 和 some() 都會跳過空位。
- map() 會跳過空位,但會保留這個值。
- join() 和 toString() 會將空位視為 undefined,而 undefined 和 null 會被處理成空字串。
ES6 則是明確將空位轉為 undefined。
- Array.from 方法會將陣列的空位,轉為 undefined。
- 擴充套件運算子(…)也會將空位轉為 undefined。
- copyWithin() 會連空位一起拷貝。
- fill() 會將空位視為正常的陣列位置。
- for…of 迴圈也會遍歷空位。
- entries()、keys()、values()、find()和 findIndex() 會將空位處理成 undefined。
參考:阮一峰《ECMAScript 6 入門》- 陣列的擴充套件 – 陣列的空位
注意: 操作的不統一可能會有產生很多意料之外的結果,所以“牆裂”建議不要建立和使用稀疏陣列。
固定長度的 undefined 陣列建立
有些時候,我們並不關心陣列的內容是什麼,我們只是需要一個真正的陣列,並且能夠使用陣列的方法。
可以參考以下方法來建立:
- Array.apply
// 這個方法也是將一個類陣列物件轉為陣列物件。
// 在建立 undefined 值的陣列時有些奇怪和繁瑣,但是結果遠比 Array(3) 更準確可靠。
Array.apply(null, {length: 4}) // [undefined, undefined, undefined, undefined]
複製程式碼
- Array.from()
// 將類陣列物件轉換為陣列物件
Array.from({length: 4}) // [undefined, undefined, undefined, undefined]
複製程式碼
- 擴充套件運算子
[...Array(4)] // [undefined, undefined, undefined, undefined]
複製程式碼
總而言之
- 不要建立和使用稀疏陣列
- 避免使用
Array
建構函式建立陣列 - 推薦物件字面量、
of()
、from()
、擴充套件運算子...
建立陣列