keywords:array
,array-likes
陣列 ( Array )
在 array 值上使用 delete 會從 array 移除指定的那個插槽 ( slot ),但它不會更新 length 特性
let f = [4,5,6]; delete f[1]; f; // [4,empty,6] f.length; // 3 f[1]; // undefined 但跟直接設定為 undefined 又不同
array 是以數值來索引,比較棘手的地方是同時也是物件,能夠將 string 鍵值 ( keys ) / 特性 ( properties ) 新增給它,但不算在 array 的 length 內 what!?
let f = []; f[0] = 1; f['abc'] = 2; f; // [1,abc:2] f[1]; // undefined f[1] = 2; f; // [1,2,abc:2] f.length; // 2 f['abc']; // 2
如果鍵值 ( key ) 的 string 能被強制轉型為標準的十進位 number ,JavaScript 會假設你想把它當成一個 number 所以來使用,而非作為一個 string 鍵值
let f = []; f['10'] = 99; f.length; // 11 f; // [ empty * 10 , 99 ]
如果要將值儲存在鍵值 / 特性中,建議就使用 object
類陣列 ( Array-Likes )
- 有一些物件在 JavaScript 很像 array 但實際上它們並不是,它們可以使用索引來訪問 array-likes 還有 .length 的特性可以使用,但它們並不會更新 .length 且不能呼叫 array 的工具函式 ex: index(..)、concat(..)、forEach(..) etc.
- 各種 DOM NodeList、用於存取函式引數所成串列的( arguments as a list )的 arguments ( ES6 中已被棄用 ) and strings
- 之前在學習程式的時候常常覺得很困惑,每次要將 DOM 選出來的 NodeList 做 forEach 或 map 都失敗,原來選出來的 NodeList 並非真正的陣列所以無法使用這些工具函式
要將類陣列轉換為陣列有三種方法:
- Array.prototype.slice.call()
- Array.from(..)
解構式 [...arrayLike]
看看例子:function f1() { let arr = Array.prototype.slice.call(arguments); console.log(arr); } f1(4,5,6); // [4,5,6]
string 🤔!? ( 下章會詳細解說 )
let f = 'abc'; f.length; // 3 f[1]; // 'b' f.forEach(item => console.log(item)); // TypeError: f.forEach is not a function
- 這三種方法在 Catalin Red 的文章裡有一個測試速度的網頁,覺得蠻有趣的,第一名是 Array.prototype.slice.call(..),而最後竟然是 Array.from(..) 還蠻意外的,有興趣可以到下方的參考文件去看看。
參考文件:
- Catalin Red - JS Array From an Array-Like Object
- Axel Rauschmayer - array-like objects