先看一个关于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]