Symbol.iterator和Symbol.asyncIterator
Symbol.iterator
Symbol.iterator为每一个对象定义了默认的迭代器。该迭代器可以被for...of循环使用。
当需要对一个对象进行迭代时(比如开始用于一个for...of循环中),它的@@iterator方法都会在不传参情况下被调用,返回的迭代器用于获取要迭代的值。
一些内置类型拥有默认的迭代器行为,其他类型(如Object)则没有。下表中的内置类型拥有默认的@@iterator方法:
- Array.prototype[@@iterator]()
- TypedArray.prototype[@@iterator]()
- String.prototype[@@iterator]()
- Map.prototype[@@iterator]()
- Set.prototype[@@iterator]()
示例
自定义迭代器
我们可以像下面这样创建自定义的迭代器:
/** 自定义迭代器 */ var myIterable = {}; myIterable[Symbol.iterator] = function* () { yield 1; yield 2; yield 3; } console.log([...myIterable])
不符合标准的迭代器
如果一个迭代器@@iterator没有返回一个迭代器对象,那么它就是一个不符合标准的迭代器,这样的迭代器将会在运行期抛出异常,甚至非常诡异的Bug
Symbol.asyncIterator
Symbol.asyncIterator符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步迭代对象,可用于for await...of循环
Symbol.asyncIterator是一个用于访问对象的@@asyncIterator方法的内建符号。一个异步可迭代对象必须要有Symbol.asyncIterator属性
示例
自定义异步可迭代对象
/** 自定义异步可迭代对象 */ const myAsyncIterable = new Object(); myAsyncIterable[Symbol.asyncIterator] = async function*() { yield "hello"; yield "async"; yield "iteration!"; } (async () => { for await (const x of myAsyncIterable) { console.log(x); } })();
内建异步可迭代对象
目前没有默认设定了[Symbol.asyncItetor]属性的JavaScript内建的对象。不过,WHATWG(网页超文本应用技术工作小组)Streams会被设定为第一批异步可迭代对象,[Symbol.asyncItertor]最近已在设计规范中落地。