Iterator 遍历器 ES6 中的 Generator Generator 的具体应用 Iterator 遍历器 ES6 中引入了很多此前没有但是却非常重要的概念,Iterator就是其中一个。Iterator对象是一个指针对象,实现类似于单项链表的数据结构,通过next()将指针指向下一个节点 ———— 这里也就是先简单做一个概念性的介绍,后面将通过实例为大家演示。 本节内容概述 简介Symbol数据类型 具有[Symbol.iterator]属性的数据类型 生成Iterator对象 Generator返回的也是Iterator对象 接下来... 简介Symbol数据类型 console.log(Array.prototype.slice) // [Function: slice] console.log(Array.prototype[Symbol.iterator]) // [Function: values] 数组的slice属性大家都比较熟悉了,就是一个函数,可以通过Array.prototype.slice得到。这里的slice是一个字符串,但是我们获取Array.prototype[Symbol.iterator]可以得到一个函数,只不过这里的[Symbol.iterator]是Symbol数据类型,不是字符串。但是没关系,Symbol数据类型也可以作为对象属性的key。如下: var obj = {} obj.a = 100 obj[Symbol.iterator] = 200 console.log(obj) // {a: 100, Symbol(Symbol.iterator): 200} 在此小节中,你只需要知道[Symbol.iterator]是一个特殊的数据类型Symbol类型,但是也可以像number string类型一样,作为对象的属性key来使用 原生具有[Symbol.iterator]属性的数据类型 在 ES6 中,原生具有[Symbol.iterator]属性数据类型有:数组、某些类似数组的对象(如arguments、NodeList)、Set和Map。其中,Set和Map也是 ES6 中新增的数据类型。 // 数组 console.log([1, 2, 3][Symbol.iterator]) // function values() { [native code] } // 某些类似数组的对象,NoeList console.log(document.getElementsByTagName('div')[Symbol.iterator]) // function values() { [native code] } 原生具有[Symbol.iterator]属性数据类型有一个特点,就是可以使用for...of来取值,例如 var item for (item of [100, 200, 300]) { console.log(item) } // 打印出:100 200 300 // 注意,这里每次获取的 item 是数组的 value,而不是 index ,这一点和 传统 for 循环以及 for...in 完全不一样 而具有[Symbol.iterator]属性的对象,都可以一键生成一个Iterator对象。如何生成以及生成之后什么样子,还有生成之后的作用,下文分解。 不要着急,也不要跳过本文的任何步骤,一步一步跟着我的节奏来看。 生成Iterator对象 定义一个数组,然后生成数组的Iterator对象 const arr = [100, 200, 300] const iterator = arr[Symbol.iterator]() // 通过执行 [Symbol.iterator] 的属性值(函数)来返回一个 iterator 对象 好,现在生成了iterator,那么该如何使用它呢 ———— 有两种方式:next和for...of。 先说第一种,next console.log(iterator.next()) // { value: 100, done: false } console.log(iterator.next()) // { value: 200, done: false } console.log(iterator.next()) // { value: 300, done: false } console.log(iterator.next()) // { value: undefined, done: true } 看到这里,再结合上一节内容,是不是似曾相识的感觉?(额,没有的话,那你就回去重新看上一节的内容吧) iterator对象可以通过next()方法逐步获取每个元素的值,以{ value: ..., done: ... }形式返回,value就是值,done表示是否到已经获取完成。 再说第二种,for...of let i for (i of iterator) { console.log(i) } // 打印:100 200 300 上面使用for...of遍历iterator对象,可以直接将其值获取出来。这里的“值”就对应着上面next()返回的结果的value属性 Generator返回的也是Iterator对象 看到这里,你大体也应该明白了,上一节演示的Generator,就是生成一个Iterator对象。因此才会有next(),也可以通过for...of来遍历。拿出上一节的例子再做一次演示: function* Hello() { yield 100 yield (function () {return 200})() return 300 } const h = Hello() console.log(h[Symbol.iterator]) // [Function: [Symbol.iterator]] 执行const h = Hello()得到的就是一个iterator对象,因为h[Symbol.iterator]是有值的。既然是iterator对象,那么就可以使用next()和for...of进行操作 console.log(h.next()) // { value: 100, done: false } console.log(h.next()) // { value: 200, done: false } console.log(h.next()) // { value: 300, done: false } console.log(h.next()) // { value: undefined, done: true } let i for (i of h) { console.log(i) } 接下来... 这一节我们花费很大力气,从Iterator又回归到了Generator,目的就是为了看看Generator到底是一个什么东西。了解其本质,才能更好的使用它,否则总有一种抓瞎的感觉。 接下来我们就Generator具体有哪些使用场景。 ES6 中的 Generator Generator 的具体应用