先看一個關於array-like和iterable的定義:javascript
Iterables and array-likes:java
There are two official terms that look similar, but are very different. Please make sure you understand them well to avoid the confusion.數組
- Iterables are objects that implement the
Symbol.iterator
method, as described above.- Array-likes are objects that have indexes and length, so they look like arrays.
由於數組實例的原型鏈上實現了 Symbol.iterator
接口,因此數組是iterable對象:this
對可迭代對象(iterable)能夠使用擴展運算符 ...
以及 for..of
循環:spa
var arr = [1, 2, 3, 4]; var arr2 = [...arr]; console.log(arr2); // 1,2,3,4,5 for (let value of arr) { console.log(value); // 1 2 3 4 5 -- 帶換行 }
而類數組(array-like)不必定實現了 Symbole.iterator
方法,若是不是iterable對象,是沒法使用[...arrlike]
擴展成數組的,也不能使用 for..of
作迭代,好比:code
var arrlike = { 0: 100, 1: 200, 2: 300, length: 3 }; var arr = [...arrlike]; // SyntaxError: Unexpected token for (let value of arrlike) { // TypeError: arrlike is not iterable console.log(value); }
有一個簡便方法能夠將iterable或array-like轉換爲數組,這個方法是 Array.form()
,其語法以下:orm
Array.from(obj[, mapFn[, thisArg]]) // 形參是巴科斯範式BNF 表示法 // 參數含義可自行查詢 MDN文檔
用法以下:對象
var arrlike = { 0: 100, 1: 200, 2: 300, length: 3 }; var arr = Array.from(arrlike); console.log(arr); // 100,200,300
對應 iterable 還能夠使用 擴展運算符來轉換成數組 [...iterable]
:blog
var iterable = { *[Symbol.iterator] () { for (let i = 1; i <= 4; i ++) { yield i; } } } var arr = [...iterable]; console.log(arr); // 1,2,3,4
在以前也看到了,對array-like 且 non-iterable的對象使用 [...arrlike]
會報錯。token
因此,不能使用擴展運算符將單純的array-like轉換爲數組!
在ECMAScript2018以後對任意對象能夠使用擴展運算符:
var obj = { a: 100, b: 200, c: 300 }; var obj2 = {...obj}; console.log(obj2); // {a: 100, b: 200, c: 300} // 可是這樣只能將對象轉換爲對象,依舊不能將 non-iterable 對象轉換爲數組 var arr = [...obj]; // 注意區別 {...obj} 與 [...iterable]