迭代器

迭代器 iterator,在 Javascript 中,迭代器是一个对象(也可称作为迭代器对象),它提供了一个 next() 方法,用来返回迭代序列中的下一项。

next 方法的定义,next 方法是一个函数,执行后返回一个对象包含两个属性:{ done: [boolean], value: [any] }



function makeIterator(array) {
var nextIndex = 0
return {
next() {
return nextIndex < array.length ?
{ value: array[nextIndex++], done: false } :
{ done: true }
}
}
} // iterator 是一个迭代器对象
var iterator = makeIterator([10, 20, 30])
iterator.next() // {value: 10, done: false}
iterator.next() // {value: 20, done: false}
iterator.next() // {value: 30, done: false}
iterator.next() // {done: true}

可迭代对象

可迭代对象必须实现一个 @@iterator 方法,也就是说在这个对象或者它的原型链上必须有一个方法名是 Symbol.iterator 的方法,当调用这个方法时它返回一个迭代器对象。

可迭代对象的表现形式为,可以使用 for...of 循环解构赋值拓展运算符(spread)yield* 这些语法来调用 Symbol.iterator 函数。也就是说这些语法糖在被调用时本质上都是在调用 Symbol.iterator 函数。

内置可迭代对象

String,Array,TypedArray,Map,Set,函数的arguments对象,NodeList对象都是内置的可迭代对象,他们的原型对象中都有一个 Symbol.iterator 方法。


// 可迭代对象
let iterable = [10, 20, 30]
// 继承自原型链
Symbol.iterator in iterable // true
iterable.hasOwnProperty(Symbol.iterator) // false for(let value of iterable){
console.log(value)
}
// 10
// 20
// 30

自定义可迭代对象

字面量对象 let o = {} 默认没有 Symbol.iterator 方法,但是我们在对象上自定义一个 @@iterator 方法,此时字面量对象也可以使用 for...of循环,拓展运算符等等语法糖。


// 字面量对象默认是不可迭代对象
// 自定义对
var myIterable = {}
myIterable[Symbol.iterator] = function(){
return {
arr: [10, 20, 30],
next: function(){
if(this.arr.length > 0){
return {value: this.arr.shift(), done: false}
}else{
return {done: true}
}
}
}
}
[...myIterable] // [10, 20, 30]

生成器

生成器 generator,在 Javascript 中生成器是一个函数(也可称作生成器函数),它可以作为创建迭代器的工厂函数。生成器函数的返回值是一个迭代器对象,同时这个对象也是一个可迭代对象。

funtion* name(){ //statement } 这种声明方式可以定义一个生成器函数。

生成器函数的语法规则是,调用一个生成器函数并不会马上执行它里面的语句,而是返回一个这个生成器的 迭代器(iterator)对象。当这个迭代器的 next() 方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield的位置为止,yield 后紧跟迭代器要返回的值。或者如果用的是 yield*(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行)。调用 next() 方法时,如果传入了参数,那么这个参数会作为上一条执行的 yield 语句的返回值。


// 生成器函数
function* generator(i){
yield i + 1
var y = yield 'foo'
yield y
} var iterator = generator(10) // 此时生成器函数不执行,返回一个迭代器 iterator.next() // {value: 11, done: false}
iterator.next() // {value 'foo', done: false}
iterator.next(10) // {value: 10, done: false},将10赋值给上一条 yield 'foo' 左侧的值,即 y = 10,返回 y
iterator.next() // {done: true}

既然 生成器函数 可以创建 迭代器对象,我们来试着将前面的例子用生成器函数的形式重写试试看。


// 生成器函数
function* makeIterator(array) {
for (let i = 0; i < array.length; i++) {
yield array[i]
}
} // 迭代器对象,实现和上文一样的功能
var iteratorByGen = makeIterator([10, 20, 30])
iteratorByGen.next() // {value: 10, done: false}
iteratorByGen.next() // {value: 20, done: false}
iteratorByGen.next() // {value: 30, done: false}
iteratorByGen.next() // {done: true}

从上面的代码我们可以看到,利用生成器函数来创建一个迭代器对象的方式相比于之前我们普通函数创建的方式更加简洁,也更加清晰的表明调用生成器函数返回的是一个迭代器对象。除此之外还有什么区别呢。

上文已经提到,生成器函数返回的是一个 可迭代的迭代器对象,这是什么意思呢?看下代码就明白了。



// 生成器函数创建的迭代器对象
Symbol.iterator in iteratorByGen // true
[...iteratorByGen] // [10, 20, 30] // 普通函数创建的迭代器对象
Symbol.iterator in iterator // false
[...iterator] // Uncaught TypeError: iterator is not iterable

综上所述,我们可以确定的说 生成器函数是创建迭代器对象的语法糖 ,通过生成器函数我们可以用很简洁清晰的语法创建一个可迭代的迭代器对象。

来源:https://segmentfault.com/a/1190000017529530

深入理解ES6之迭代器与生成器的更多相关文章

  1. 深入理解ES6之——迭代器与生成器

    迭代器 迭代器是被设计专用于迭代的对象,带有特定接口.所有的迭代器对象都有next方法,会返回一个结果对象.该结果对象有两个属性:对应下一个值的value,以及一个布尔类型的done,其值为true时 ...

  2. 【ES6】迭代器与可迭代对象

    ES6 新的数组方法.集合.for-of 循环.展开运算符(...)甚至异步编程都依赖于迭代器(Iterator )实现.本文会详解 ES6 的迭代器与生成器,并进一步挖掘可迭代对象的内部原理与使用方 ...

  3. pytorch :: Dataloader中的迭代器和生成器应用

    在使用pytorch训练模型,经常需要加载大量图片数据,因此pytorch提供了好用的数据加载工具Dataloader. 为了实现小批量循环读取大型数据集,在Dataloader类具体实现中,使用了迭 ...

  4. ES6深入浅出-4 迭代器与生成器-3.生成器 & for...of

    迭代器平时用的很少.但是如果你是写框架的,你会经常用到迭代器. 生成器是专门用来做迭代器的东西 发布器是要产生一个叫做next的对象,如果你要产生这种对象.就可以使用ES6新出的语法. ES6的新语法 ...

  5. 理解Python迭代对象、迭代器、生成器

    作者:zhijun liu链接:https://zhuanlan.zhihu.com/p/24376869来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 本文源自RQ作 ...

  6. 完全理解 Python 迭代对象、迭代器、生成器(转)

    完全理解 Python 迭代对象.迭代器.生成器 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Generators » nvie.com,俺写的这篇文章是 ...

  7. 完全理解 Python 迭代对象、迭代器、生成器

    完全理解 Python 迭代对象.迭代器.生成器 2017/05/29 · 基础知识 · 9 评论 · 可迭代对象, 生成器, 迭代器 分享到: 原文出处: liuzhijun    本文源自RQ作者 ...

  8. [转载]完全理解Python迭代对象、迭代器、生成器

    译文地址:liuzhijun 在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导 ...

  9. python 进阶篇 迭代器和生成器深入理解

    列表/元组/字典/集合都是容器.对于容器,可以很直观地想象成多个元素在一起的单元:而不同容器的区别,正是在于内部数据结构的实现方法. 所有的容器都是可迭代的(iterable).另外字符串也可以被迭代 ...

随机推荐

  1. block知识点

    1.block引用局部变量的时候,该变量会作为常量编码到block中,在block中不能被修改. 2.使用 __block修饰的局部变量,不会作为常量被编码到block中,故而在block中可以被修改 ...

  2. ASP.NET CORE RAZOR :将搜索添加到 Razor 页面应用

    https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/search 本文档中,将向索引页面添加搜索功能以实现按“流派”或 ...

  3. python判断值是否为空

    代码中经常会有变量是否为None的判断,有三种主要的写法: 第一种是`if x is None`: 第二种是 `if not x:`: 第三种是`if not x is None`(这句这样理解更清晰 ...

  4. Unity3D性能优化之Draw Call Batching

    在屏幕上渲染物体,引擎需要发出一个绘制调用来访问图形API(iOS系统中为OpenGL ES).每个绘制调用需要进行大量的工作来访问图形API,从而导致了CPU方面显著的性能开销. Unity在运行时 ...

  5. synchronized 锁优化

    synchronized 在jdk 1.7之前是重量级锁,独占锁,非公平锁.jdk1.7之后,synchronized引入了 偏向锁,自旋锁,轻量级锁,重量级锁 自旋锁 当线程在获取锁的时候,如果发现 ...

  6. 基于日志处理的ElasticSearch的学(gen)习(feng)

    最近学了点solr,然后有听说了ElasticSearch,就想着也学一下ElasticSearch,然后看见了ElasticSearch用于日志的收集的分析,这里就来学习一下. 百度一下Elasti ...

  7. 《TomCat与Java Web开发技术详解》(第二版) 第六章节的学习总结 ---- JSP技术

    第六章主要介绍了JSP的相关知识. 1.JSP:是通过在HTML文件中加入java程序片段(Java Scriptlet)和JSP标记,就构成了JSP文件.JSP实质上是Servlet.JSP的API ...

  8. CLR内存回收总结,代龄机制

    关键字:对象可达图,代龄机制,终止化对象. 代龄机制: 0代满了之后,GC开始回收,剩下的对象升级为1代.(只有不可达的对象才会被回收.) 0代再回收几次之后,1代的对象慢慢增多然后达到阈值,GC同时 ...

  9. [转]postman 官方文档解说

    1. 安装 两种安装方式,我热衷于以chrome插件形式安装 Chrome插件 Mac App 2. 发送请求 Postman最基础的功能就是发送http请求,支持GET/PUT/POST/DELET ...

  10. mac地址绑定

    1.导入第三方类库: <?php /** * FILE_NAME : Macaddr.php * linux平台获取服务器mac地址 * @filesource */ class Macaddr ...