什麼是Array-like?

偽陣列物件的特性、轉化陣列的相關方法

Timothy Liao
Coding & Learning
Aug 31, 2021

--

說明

在學習的時候,有時會遇到某東西被稱為Array-like,並且要注意不要錯把他當成陣列等等的,後來知道其實全名為Array-like object,顧名思義是一個很像是陣列的物件,聽起來很像廢話,不過既然是很像陣列,代表這個物件也具有部份陣列的特性。

特性

  1. 可以使用索引值取值
  2. 本身不具有陣列方法,但可以透過Array.prototype直接移植陣列方法做使用
  3. 有length屬性
  4. 可遍歷

常見的Array-like Object包括:

  • 函數內部的 arguments
  • DOM 對象列表(比如 document.querySelectorAll 得到的lists)

製作一個Array-like Object

若我們要自己製作一個Array-like Object要怎麼做呢?

  1. 屬性要為索引(數字)值
  2. 一定要有length屬性存在

參考來自於前輩的範例:

與陣列之間的關係

如果有注意到那個push,事實上他是完全可以運作的,這也是我覺得最有趣的部份之一,console後的結果見下圖:

圖1

不是說他不是陣列嗎?為什麼可以使用陣列的push?

原因來自於push被實作的方式,以下借用

https://s95050937.github.io/JS_post01.html

沒辦法完全看懂無所謂,重點在於,push的必要參數就只有length屬性而已,於是只要有length,其實都可以借用Array.prototype.push來使用。

除了push,絕大部分的陣列方法都可以這樣被借用,像是slice, pop...等。

借用方式有兩種:

  • 按照前面的方式,為Object增加新屬性,其值設定為Array.prototype.<method>。
  • 透過apply, call等重新綁定this的方法直接呼叫Array.prototype.<method>,並指定this要綁定的對象為Array-like Object

舉例來說,借用最一開始的範例,想要直接使用push方法又不想要賦值新的屬性的話,可以這樣做。

這樣後續console結果跟圖1是一模一樣的~。

轉化真●陣列的方法

那要如何將Array-like Object轉換為真陣列呢?

有三種方法是我知道的:

  • 遍歷每個屬性並貼到新的陣列裡面
  • 透過Array.prototype.slice.call將整個陣列切割並複製
https://www.gushiciku.cn/pl/gbc7/zh-tw
  • 使用Array.from產生新的陣列出來

底下幾個console是為了測試某變數是否為陣列,包括是否為Array及Object的實例、是否能使用索引值取值、是否包含forEach函式等。

那差不多就這樣啦~~

參考資料

--

--