此篇主要講解 Array-like 和一般陣列有什麼差異,最後也會介紹三種將類陣列轉成陣列的方法。
Array-like
Array-like object 就是一個類陣列物件(很像陣列的物件),和一般陣會最大差異就是,類陣列沒有
陣列內建的方法。
常見的類陣列
- arguments object
- 函式中用來接收所有引數。
- HTMLCollection
- 透過方法(ex:getElementsByTagName)取得的 DOM 物件。
- NodeList
- 透過方法(ex:querySelectorAll)取得的節點集合。
要注意,類陣列 不是真正
的陣列。
類陣列特性
- 可以使用
索引值
取得值。 - 可以使用
length
屬性。 - 可以使用
callee
屬性。- callee 可以當作是一個指標,指向函式本身。
- 對於匿名函式中特別有用,例如:讓匿名函式也可以進行遞迴(但在 ES5 嚴格模式底下已禁用,詳細原因請參考 MDN)
沒有
陣列內建的方法
。(ex:indexOf、concat、forEach)
1 | function add(num1, num2) { |
下方圖片為 console.log(arguments, arr);
的結果,可以從 Prototype 看出 arguments object 中沒有
內建陣列方法。
雖然上述類陣列看起來這麼不方便,但可以將類陣列轉為
陣列,來使用陣列方法。
類陣列轉陣列的三種方法
下列介紹的三種都屬於淺拷貝(shallow-copied)的方式
- ES5 slice:
Array.prototype.slice.call(arguments);
- ES6 Array.from:
Array.from(arguments)
- ES6 Rest parameters(解構式):
[...arguments];
1 | function add(num1, num2) { |
由下方圖片的中的 Prototype 看得出來三者皆是陣列。
下方會透過效能、支援度這兩個方面來對這三種方法做比較
performance 效能差異
圖片來自 JS array from an array-like object 文章,內文中有對上述提到的三種方法,進行效能的評測。
從上方圖片可得知 slice
方法的速度是較快的,優於另外兩種方法不少。
support 支援度
下方截圖是來自 caniuse,比對上述三種方法對於瀏覽器的支援度。
最後結果可以得知 slice
方法的支援度是最好的。
conclusion
上述三種方法若從效能和支援度方面來看,slice
勝。