深入理解ES6之——迭代器与生成器
迭代器
迭代器是被设计专用于迭代的对象,带有特定接口。所有的迭代器对象都有next方法,会返回一个结果对象。该结果对象有两个属性:对应下一个值的value,以及一个布尔类型的done,其值为true时表示没有更多对值可供使用。
//es5创建迭代器
function createIterator(items) {
var i = 0;
return {
next: function() {
var done = (i >= items.length);
var value = !done ? items[i++] : "undefined";
return {
done: done,
value: value
}
}
}
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next());//{done:false,value:1}
console.log(iterator.next());//{done:false,value:2}
console.log(iterator.next());//{done:false,value:3}
console.log(iterator.next());//{done:true,value:"undefined"}
console.log(iterator.next());//{done:true,value:"undefined"}
生成器
生成器是一个能返回迭代器的函数。生成器函数由放在function关键字之后的一个星号(*)来表示,并使用新的yield关键字(指定迭代器在被next()方法调用时应当按顺序返回的值。)。
function* createIterator() {
yield 1;
yield 2;
yield 3;
}
var iterator = createIterator();
console.log(iterator.next());//{done:false,value:1}
console.log(iterator.next());//{done:false,value:2}
console.log(iterator.next());//{done:false,value:3}
console.log(iterator.next());//{done:true,value:undefined}
console.log(iterator.next());//{done:true,value:undefined}
生成器最有意思的方面可能就是它们会在每个yield语句后停止执行。
//yield语句在for循环中的使用
function* createIterator(items) {
for (let i = 0, len = items.length; i < len; i++) {
yield items[i];
}
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next());//{done:false,value:1}
console.log(iterator.next());//{done:false,value:2}
console.log(iterator.next());//{done:false,value:3}
console.log(iterator.next());//{done:true,value:undefined}
console.log(iterator.next());//{done:true,value:undefined}
yield只能用于生成器内部,用于其他任何位置都会报错,即使在生成器内部的函数中也不行。因为yield无法穿越函数边界。从这点上来说,yield与return非常相似。
function *createIterator(items){
items.forEach(function(item){
yield item+1;//语法错误
})
}
生成器函数表达式
你可以使用函数表达式来创建一个生成器,只需要在function关键字与圆括号之间使用一个星号(*)即可。
生成器对象方法
var o = {
*createIterator(items){
for (let i = 0, len = items.length; i < len; i++) {
yield items[i];
}
}
}
可迭代对象与for-of循环
可迭代对象被设计用于与es新增的for-of循环配合使用。
for-of循环在循环每次执行时会调用可迭代对象的next()方法,并将结果对象的value储存在一个变量上。循环过程会持续到结果对象的done属性编程true为止。
let values = [1, 2, 3];
for (let num of values) {
console.log(num);
}
//输出内容为
1,2,3
let set = new Set([1, 3, 3, 2, 4, 5, 1, 3]);
for (let val of set) {
console.log(val);
}
//输出内容为
1,3,2,4,5
let map = new Map();
map.set("name", "cc");
map.set("age", 26);
for (let val of map) {
console.log(val);
}
//输出内容为
["name","nicolas"]
["age",52]
访问默认迭代器
你可以使用Symbo.iterator来访问对象上的默认迭代器。
let values = [1, 2, 3];
var iterator = values[Symbol.iterator]();
console.log(iterator.next());//{value:1,done:false}
console.log(iterator.next());//{value:2,done:false}
console.log(iterator.next());//{value:3,done:false}
console.log(iterator.next());//{value:undefined,done:true}
内置的迭代器
集合的迭代器
ES6具有三种集合对象类型:数组、Map和Set。这三种类型都拥有如下迭代器:
- entries():返回一个包含键值对的迭代器
- values():返回一个包含集合中值的迭代器
- keys():返回一个包含集合中键的迭代器
let colors = ["red", "green", "blue"];
let set = new Set([1234, 5678, 9012]);
let map = new Map();
map.set("title", "unde");
map.set("format", "ebook");
//entries
for (let entry of colors.entries()) {
console.log(entry);
}
for (let entry of set.entries()) {
console.log(entry);
}
for (let entry of map.entries()) {
console.log(entry);
}
//values
for (let value of colors) {
console.log(value);
}
for (let value of set.values()) {
console.log(value);
}
for (let value of map.values()) {
console.log(value);
}
//keys
for (let key of colors.keys()) {
console.log(key);
}
for (let key of set.keys()) {
console.log(key);
}
for (let key of map.keys()) {
console.log(key);
}
字符串的迭代器
let message = "A B";
for (let s of message) {
console.log(s);
}
//输出内容为
A
(BLANK)
(BLANK)
B
NodeList的迭代器
let p = document.getElementsByTagName("p");
for (let c of p) {
console.log(c.className);
}
传递参数给迭代器
function* createIterator() {
let first = yield 1;
let second = yield first + 2;
yield second + 3;
}
let iterator = createIterator();
console.log(iterator.next());//1
console.log(iterator.next(4));//6
console.log(iterator.next(5));//8
在包含赋值操作的第一个yield语句中,表达式右侧再第一次调用next()时被计算,而表达式左侧则在第二次调用next()方法时,并在生成器函数执行之前被计算。
生成器委托
function* createNumI() {
yield 1;
yield 2;
}
function* createColI() {
yield "red";
yield "green";
}
function* createComb() {
yield* createNumI();
yield* createColI();
yield true;
}
let iterator = createComb();
console.log(iterator.next());//{value:1,done:false}
console.log(iterator.next());//{value:2,done:false}
console.log(iterator.next());//{value:"red",done:false}
console.log(iterator.next());//{value:"green",done:false}
console.log(iterator.next());//{value:true,done:false}
console.log(iterator.next());//{value:undefined,done:false}
深入理解ES6之——迭代器与生成器的更多相关文章
- 深入理解ES6之迭代器与生成器
迭代器 迭代器 iterator,在 Javascript 中,迭代器是一个对象(也可称作为迭代器对象),它提供了一个 next() 方法,用来返回迭代序列中的下一项. next 方法的定义,next ...
- 【ES6】迭代器与可迭代对象
ES6 新的数组方法.集合.for-of 循环.展开运算符(...)甚至异步编程都依赖于迭代器(Iterator )实现.本文会详解 ES6 的迭代器与生成器,并进一步挖掘可迭代对象的内部原理与使用方 ...
- pytorch :: Dataloader中的迭代器和生成器应用
在使用pytorch训练模型,经常需要加载大量图片数据,因此pytorch提供了好用的数据加载工具Dataloader. 为了实现小批量循环读取大型数据集,在Dataloader类具体实现中,使用了迭 ...
- ES6深入浅出-4 迭代器与生成器-3.生成器 & for...of
迭代器平时用的很少.但是如果你是写框架的,你会经常用到迭代器. 生成器是专门用来做迭代器的东西 发布器是要产生一个叫做next的对象,如果你要产生这种对象.就可以使用ES6新出的语法. ES6的新语法 ...
- 理解Python迭代对象、迭代器、生成器
作者:zhijun liu链接:https://zhuanlan.zhihu.com/p/24376869来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 本文源自RQ作 ...
- 完全理解 Python 迭代对象、迭代器、生成器(转)
完全理解 Python 迭代对象.迭代器.生成器 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Generators » nvie.com,俺写的这篇文章是 ...
- 完全理解 Python 迭代对象、迭代器、生成器
完全理解 Python 迭代对象.迭代器.生成器 2017/05/29 · 基础知识 · 9 评论 · 可迭代对象, 生成器, 迭代器 分享到: 原文出处: liuzhijun 本文源自RQ作者 ...
- [转载]完全理解Python迭代对象、迭代器、生成器
译文地址:liuzhijun 在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导 ...
- python 进阶篇 迭代器和生成器深入理解
列表/元组/字典/集合都是容器.对于容器,可以很直观地想象成多个元素在一起的单元:而不同容器的区别,正是在于内部数据结构的实现方法. 所有的容器都是可迭代的(iterable).另外字符串也可以被迭代 ...
随机推荐
- django使用xlwt导出excel文件
这里只是mark一下导出的方法,并没有做什么REST处理和异常处理. 维护统一的style样式,可以使导出的数据更加美观. def export_excel(request): # 设置HttpRes ...
- Echarts数据可视化全解注释
全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...
- c#字符编码,System.Text.Encoding类,字符编码大全:如Unicode编码、GB18030、UTF-8,UTF-7,GB2312,ASCII,UTF32,Big5
本页列出来目前window下所有支持的字符编码 ---c#通过 System.Text.Encoding.GetEncodings()获取,里面可以对其进行查询,筛选,对同一个字符,在不同编码进行查 ...
- JAVA基础总结2
2.1 关键字 常用的关键字主要包括如下: 2.2 标识符 简单而言标识符它其实就是用于标识某些东西的符号. 2.3 注释的应用 注释说明 注释的作用: 注释的应用: 2.4 常量和变量 常量的定义与 ...
- C#设计模式之八桥接模式(Bridge)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第二个模式,该模式是[桥接模式],也有叫[桥模式]的.大家第一次看到这个名称会想到什么呢?我第一次看到这个模式根据名称猜肯定是连接什么东西的.因为桥在我们现实 ...
- .NET下发送邮件遇到问题及解决方案
.NET后台代码利用QQ邮箱服务器发送邮件遇到的问题: "mail from address must be same as authorization user" 首先,看下我的 ...
- KindEditor文件上传成功前端显示上传失败
一.使用kindeditor 上传图片 ,根据kindeditor 要求返回了相应的数据, 但是kindeditor 插件显示上传失败!!! 解决方法: 各个版本位置可能不同!!! 1.修改kinde ...
- 面向接口编程实现不改代码实现Redis单机/集群之间的切换
开发中一般使用Redis单机,线上使用Redis集群,因此需要实现单机和集群之间的灵活切换 pom配置: <!-- Redis客户端 --> <dependency> < ...
- LeetCode 40. Combination Sum II (组合的和之二)
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in ...
- linux root修改密码失败
问题: 当使用root修改密码时,报错passwd:Authentication token manipulation error 解决: 1.查看是否权限问题, /etc/passwd /etc/s ...