数组是可迭代的,所以数组可以用于for of,字符串也是可迭代的,所以字符串也可以用作for of,那么,对象呢?
试一试:
var somebody = { start:0, end:100 } for (const iterator of somebody) { console.log(iterator); } //somebody is not iterable
如你所见,not iterable!,但是我们可以把一个对象定制成可迭代的,接下来:
Symbol.iterator
是一个对象的内置方法,可以使我们定制对象的迭代过程,需要注意的是,该方法必须返回一个迭代器(带有next方法的对象)
代码如下:
const range = { from: 1, to: 5, [Symbol.iterator]() { this.current = this.from; return this;//返回自己, }, next() { // 必须有next方法,next方法必须返回一个具有done和value属性的对象,当done为true,value可以省略 if (this.current <= this.to) { return { done: false, value: this.current++ }; } return { done: true }; } } for (const iterator of range) { console.log('iterator-',iterator); } /** iterator- 1 iterator- 2 iterator- 3 iterator- 4 iterator- 5 */
this.current属性是我为了控制迭代流程而自定义的;
Array.from可以将一个可迭代对象转换为数组,数组的值就是可迭代对象的迭代器运行返回的值
console.log(Array.from(range)); //[ 1, 2, 3, 4, 5 ]
Array.from 完整语法是这样的,Array.from(obj,mapFn,thisArg);
我们可以通过mapFn映射函数来处理数组的值,并且可以给该函数指定this;
const thisArg = {sign:'SNS-'} let results = Array.from(range,function(num){ return `${this.sign}${num}`; },thisArg) console.log(results); // [ 'SNS-1', 'SNS-2', 'SNS-3', 'SNS-4', 'SNS-5' ]