c++迭代器iterator通用吗_「ES6基础」迭代器(iterator)
迭代器(iterator)是一个结构化的模式,用于从源以一次一个的方式提取数据。迭代器的使用可以极大地简化数据操作,于是ES6也向JS中添加了这个迭代器特性。新的数组方法和新的集合类型(如Set集合与Map集合)都依赖迭代器的实现,这个新特性对于高效的数据处理而言是不可或缺的,在语言的其他特性中也都有迭代器的身影:新的for-of循环、展开运算符(...),甚至连异步编程都可以使用迭代器。
今天笔者将从以下几个方面进行介绍迭代器:
- 什么是迭代器(iterator)?
- 基于协议实现迭代器
- 迭代器的应用
本篇文章阅读时间预计6分钟。
迭代器(iterator)
迭代器是一种有序、连续的、基于拉取的用于消耗数据的组织方式,用于以一次一步的方式控制行为。简单的来说我们迭代循环一个可迭代对象,不是一次返回所有数据,而是调用相关方法分次进行返回。
迭代器iterator是一个object,这个object有一个next函数,该函数返回一个有value和done属性的object,其中value指向迭代序列中当前next函数定义的值。
ES6的迭代协议分为迭代器协议(iterator protocol)和可迭代协议(iterable protocol),迭代器基于这两个协议进行实现。
迭代器协议: iterator协议定义了产生value序列的一种标准方法。只要实现符合要求的next函数,该对象就是一个迭代器。相当遍历数据结构元素的指针,类似数据库中的游标。
可迭代协议: 一旦支持可迭代协议,意味着该对象可以用for-of来遍历,可以用来定义或者定制JS 对象的迭代行为。常见的内建类型比如Array & Map都是支持可迭代协议的。对象必须实现@@iterator方法,意味着对象必须有一个带有@@iterator key的可以通过常量Symbol.iterator访问到的属性。
下图展示了arrays,Maps,Strings数据类型实现了可迭代协议,我们可以使用for-of和展开语法显示迭代器的数据。
基于协议实现迭代器
迭代器协议
如下代码展示了基于迭代协议进行实现:
let obj = { array: [1, 2, 3, 4, 5], nextIndex: 0, next: function() { return this.nextIndex < this.array.length ? {value: this.array[this.nextIndex++], done: false} : {done: true} }};console.log(obj.next().value);console.log(obj.next().value);console.log(obj.next().value);console.log(obj.next().value);console.log(obj.next().value);console.log(obj.next().done);
上述代码将会输出
12345true
上述代码的next方法还可以按如下代码进行改写,看起来更清晰些:
if(this.nextIndex < this.array.length) { this.nextIndex++; return { value: this.array[this.nextIndex], done: false }} else { return { done: true }}
我们可以看出,next方法的实现,如果存在新的元素,返回当前元素的并将当前元素位置的标识递增加1,当没有元素时,返回{ done: true }。
可迭代协议
根据可迭代协议,对象需要提供@@iterator方法; 也就是说,它必须将Symbol.iterator符号作为属性键。 @@iterator方法必须返回迭代器对象。代码实现如下:
let obj = { array: [1, 2, 3, 4, 5], nextIndex: 0, [Symbol.iterator]: function(){ return { array: this.array, nextIndex: this.nextIndex, next: function(){ return this.nextIndex < this.array.length ? {value: this.array[this.nextIndex++], done: false} : {done: true}; } } }};let iterable = obj[Symbol.iterator]()console.log(iterable.next().value);console.log(iterable.next().value);console.log(iterable.next().value);console.log(iterable.next().value);console.log(iterable.next().value);console.log(iterable.next().done);
上述代码将会输出
12345true
上述代码,我们实现了自定义的迭代器,基于JS的作用域和闭包特性才能轻松实现。arrays,Maps,Strings数据类型实现了可迭代协议,其 __proto__原型链指向自带Symbol.iterator的方法,节省了我们手写代码的时间,如下代码所示:
const arr = [1, 2];const iterator = arr[Symbol.iterator](); // returns you an iteratorconsole.log(iterator.next())console.log(iterator.next())console.log(iterator.next())
上述代码将会输出:
{ value: 1, done: false }{ value: 2, done: false }{ value: undefined, done: true }
我们可以使用for-of,展开语法迭代数组,示例代码如下:
const arr = [1, 2];for(var v of arr){ console.log(v);}//outputs 1//outputs 2console.log([...arr]);//outputs[1,2];
obj对象没有实现可迭代协议,我们如何迭代obj对象呢?实现obj的迭代器呢,示例代码如下:
var obj={ a:1, b:2, c:3, [Symbol.iterator]:function () { var keys=Object.keys(this);//object.vulues(this) var index=0; return{ next:()=> (index
迭代器应用
斐波那契数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)。
我们可以使用迭代器来产生一个序列数不大于100的斐波那契数列,示例代码如下:
let Fib= { [Symbol.iterator](){ let n1=1; let n2=1; let max=100; return { next(){ let current=n2; n2=n1; n1=n1+current; if(current
模拟任务队列
有时候我们需要要执行任务放在一个队列里,分次执行,我们可以使用迭代器进行模拟,示例代码如下:
let tasks={ actions:[], [Symbol.iterator](){ let steps=this.actions.slice(); return { [Symbol.iterator]() {return this;}, next(...args){ if(steps.length>0){ let res=steps.shift()(...args); return {value:res,done:false}; } else{ return {done:true} } }, return(v){ steps.length=0; return {value:v,done:true}; } }; }};tasks.actions.push( function step1(x) { console.log("step 1:
c++迭代器iterator通用吗_「ES6基础」迭代器(iterator)相关推荐
- doctrine find的对象转换成数组_「ES6基础」Array数组的新方法(上)
在日常工作中我们经常会与数组打交道,因此需要熟练掌握数组操作的相关方法,ES6中关于数组的操作,又给我们带来了哪些惊喜呢,Array数组操作又添加了哪些新方法? 本篇文章将从以下几个方面进行介绍: A ...
- 如何修改Series和DataFrame类型中的元素值_「ES6基础」Symbol介绍:独一无二的值
ES6之前我们都清楚JS有六种数据类型:Undefined.Null.布尔值(Boolean).字符串(String).数值(Number).对象(Object),今天笔者讲的Symbol类型是ES6 ...
- python中的与或非_「Python基础」 While 循环语句
Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务.其基本形式为: while 判断条件: 执行语句-- 执行语句可以是单个语句或语句 ...
- javascript进制转换_「js基础」JavaScript逻辑和位运算符归纳
上一篇文章呢,我们讲述了JavaScript运算符中的关系运算符和逻辑运算符,那么紧接上一篇的文章我们今天来说说逻辑运算符. 引言 逻辑运算符不是很难,也不是很多,我们只要记住三个就可以啦!分别是: ...
- python 教学_「Python基础」一次就装好Python手把手装到好
一.前言: 安装Python有两个主要的方法,视情况而定我两个都会用: (1)安装 Anaconda Anaconda像一个懒人包,安装它等于把Python安装好连同把Python大部分的套件也下载好 ...
- 32 位的有符号整数_「js基础」JavaScript逻辑和位运算符归纳
上一篇文章呢,我们讲述了JavaScript运算符中的关系运算符和逻辑运算符,那么紧接上一篇的文章我们今天来说说逻辑运算符. 引言 逻辑运算符不是很难,也不是很多,我们只要记住三个就可以啦!分别是: ...
- python 搜索引擎 词位置加权_「seo基础」关键词推广:如何增加网站内容相关
如何增加网站内容相关性,很多SEO常常会听到圈内人士大夫强调网站内容相关性.网站垂直等之类的言词,网站内容相关性高低也是决定关键词排名重要的环境因素之一,很多小鸟也问过大宝什么是网站内容相关性,如何提 ...
- 「软件测试基础」理论篇之软件测试概论
文章目录 1. 软件 1.1 软件发展史 1.2 软件生命周期 1.3 软件缺陷 1.4 三种纠错技术 2. 软件过程 2.1 RUP 2.1.1 RUP各个阶段 2.1.2 RUP核心工作流 2.2 ...
- 「上层建筑」与「结构基础」~不被迷惑
数据结构的存储方式 数据结构的存储方式只有两种:数组(顺序存储)和链表(链式存储). 我们分析问题,一定要有递归的思想,自顶向下,从抽象到具体.散列表.栈.队列.堆.树.图等这些都属于「上层建筑」,而 ...
最新文章
- pdf批量添加图章_关于添加图章,过来人有哪些实用经验
- 沈向洋:浅谈人工智能创造
- 关于异步提交form表单
- Python基础教程:内置类型之比较
- 用Java描述数据结构之栈和队列,以及栈和队列的常用方法
- HTML5尝鲜(1):使用aduio标签打造音乐播放器
- java基于springboot+vue学生考勤签到请假管理系统84y43
- Canon EOS Utility安装和使用说明
- Unity利用SMSSDK实现短信验证码(附源代码)
- 关于运行微信小程序报错 [微信小程序开发者工具] Error: read EBADF
- java 基础 String str= “abc god 中国 java“ 反转每个单词 结果: “cba dog 国中
- 【AnySDK】项目实战教程
- 巴山铁路工人吴磊自学在云上开发文件签报系统,把紧急通知及时送到铁路工人手中,确保行车安全...
- 中国玉米面筋行业市场供需与战略研究报告
- 新电脑从另外一台电脑完整拷贝环境,不需要安装环境
- 老罗斯柴尔德的第一桶金
- polished css,CSS in JS
- php发布文章时 未定义索引,关于php:提交表单时未定义索引错误
- 嵌入式和Python(一):python环境搭建的详细步骤
- react学习(一)
热门文章
- jpa写原生sql-EntityManager
- godaddy php5.ini,Godaddy主机如何开启GZIP压缩 | Godaddy美国主机中文指南
- 数据库物理文件 mysql_MYSQL数据库-物理文件
- 一看就知道的Java8日期处理全方位实践
- Elasticsearch之倒排索引
- 值类型 与引用的 copy
- matlab定子磁链观测器,一种基于二阶广义积分器的永磁同步电机定子磁链观测方法...
- ACM寒假训练第二周总结
- 贪吃蛇python零基础教程_自学python-tkinter项目-贪吃蛇的程序(0基础入门学习)...
- 电子计算机微机调试员,电子计算机(微机)装配调试员国家职业标准