JavaScript中,數組是一個特殊的對象,其property名為正整數,且其length屬性會隨着數組成員的增減而發生變化,同時又從Array構造函數中繼承了一些用於進行數組操作的方法。
而對於一個普通的對象來說,如果它的所有property名均為正整數,同時也有相應的 length 屬性,那么雖然該對象並不是由Array構造函數所創建的,它依然呈現出數組的行為,在這種情況下,這些對象被稱為 “類數組對象” 。
var o = {0:42,1:52,2:63,length:3} console.log(o); // 返回:{0: 42, 1: 52, 2: 63, length: 3}
console.log(o.length); // 返回3
與普通對象不同的是,類數組對象擁有一個特性:可以在類數組對象上應用數組的操作方法。比如,在ECMAScript 5標准中,可以用以下方法來將上面的對象o合並成字符串:
var o = {0:42,1:52,2:63,length:3} console.log(Array.prototype.join.call(o));// “42,52,63”
將類數組對象轉換成普通數組,下面分別介紹兩種方法:
法一: 可以使用 Array.prototype.slice.call() 方法。
// ES5的寫法
var o = {0:42,1:52,2:63,length:3} console.log(Array.prototype.slice.call(o)); // [42, 52, 63]
法二: Array.from
方法用於將兩類對象轉為真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)的對象(包括ES6新增的數據結構Set和Map)。
// ES6的寫法
var o = {0:42,1:52,2:63,length:3}
console.log(Array.from(o)) // [42,52,63]
在瀏覽器環境中,document.getElementsByTagName()語句返回的就是一個類數組對象。在function調用中,function代碼內的arguments變量(保存傳入的參數)也是一個類數組對象。
在ECMAScript 5標准中,字符串string就是一個只讀的類數組對象:
var s = "History"; console.log(s[3]); // t
console.log(s.length) // 7
console.log(Array.prototype.join.call(s, " ")); // H i s t o r y
擴展運算符(...
)也可以將某些數據結構轉為數組。擴展運算符背后調用的是遍歷器接口(Symbol.iterator
),如果一個對象沒有部署這個接口,就無法轉換。Array.from
方法還支持類似數組的對象。所謂類似數組的對象,本質特征只有一點,即必須有length
屬性。因此,任何有length
屬性的對象,都可以通過Array.from
方法轉為數組,而此時擴展運算符就無法轉換。
Array.from({ length: 3 }); // [ undefined, undefined, undefined ]
上面代碼中,Array.from
返回了一個具有三個成員的數組,每個位置的值都是undefined
。擴展運算符轉換不了這個對象。
Array.from()
可以將各種值轉為真正的數組,並且還提供map
功能。這實際上意味着,只要有一個原始的數據結構,你就可以先對它的值進行處理,然后轉成規范的數組結構,進而就可以使用數量眾多的數組方法。
Array.from({ length: 2 }, () => 'jack') // ['jack', 'jack']