此篇主要講解 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 勝。