好久没发文章啦-。-为了证明我还活着,我决定从笔记里面抓一篇还算不乱比较像文章的发出来。。。
  这些笔记是我在学es6的时候断断续续记录的,最近会一份一份整理陆陆续续发出来,顺便也自己再看一遍。我学习es6的时候主要是阅读的阮一峰大神的文章,有需要的可以搜索来阅读,很系统。
  
1.概念
  第一次看到这个概念是当年学C++的时候,STL库中的迭代器。在es6中,Iterator也差不多是这个意思。
  在es6中,能表示“集合”概念的数据类型大致有四种。  
  Array,Object,Map,Set
 
  既然是集合,那遍历便是一种基本需求。而Iterator就是为了提供一种统一的接口机制。任何的数据结构,只要部署了Iterator接口,便可以使用类似的方式完成遍历操作。
 
  当然,Iterator还有2个作用,它使数据结构的成员按某种次序排列,其次,es6有一种新的遍历方式,前面也说过,for...of,而Iterator的主要作用,就是支持此操作。
 
  Iteartor的遍历过程和C++语言一样
  1)创建一个指向数据结构起始位置的指针。(起始位置不是第一个成员的位置,起始位置使一个单独的标志位。)
  2)当调用next()方法,指针就向后移动一个位置,并返回当前位置上的成员,直到指针指向数据结构的结束位置为止。
 
  第二步中,js语言返回的的成员信息是两个,value和done,value不用介绍,done是一个表示遍历是否结束的布尔值。
 
 
2.部署接口
  上面我们说到的部署接口,那js怎么部署接口呢。其实我们之前已经说到过,在Symbol一节中,介绍了很多es6内置的Symbol值,这些就是接口。
  es6中有三类结构生来就具有Iterator接口:数组、类数组对象、Map和Set结构。
  

var arr = [1,2,3,4];
let iterator = arr[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: 4, done: false }
console.log(iterator.next()); //{ value: undefined, done: true }
 
 
  至于对象没有布置iterator接口的原因,不知道最近大家有没有看根据《你一生的故事》拍成的电影“降临",片中出现的外星语言是一门非线性的语言。而我们说的数组,Map等结构中的成员都是有顺序的,即都是线性的结构,而对象,各成员并没有一个确定的顺序,所以遍历时先遍历谁后遍历谁并不确定。所以,给一个对象部署iterator接口,其实就是对该对象做一种线性转换。如果你有这种需要,就需要手动给你的对象部署iterator接口咯~
  如:
  

let obj = {
data: [ 'hello', 'world' ],
[Symbol.iterator]() {
const self = this;
let index = 0;
return {
next() {
if (index < self.data.length) {
return {
value: self.data[index++],
done: false
};
} else {
return { value: undefined, done: true };
}
}
};
}
};
 
  可以看到,Symbol.iterator会返回一个对象,这就是一个遍历器对象,而作为遍历器对象,其必须具备的特征就是必须具备next()方法。
我们还可以据此实现指针结构的数据结构。具体略~
 
  至于可以使用Array.from转换成数组的类数组对象,部署iterator有一种很简单的方法,即直接使用数组的[Symbol.iterator]接口。
  

fakeArray.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
  当然,不知道你们看到next是否想到了es6的一个新玩意儿,即Generator函数。用Generator函数来实现Symbol.iterator接口,事半功倍。
  

var yieldIterator = {};
yieldIterator[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
}; [...yieldIterator] // [1, 2, 3]
 
  注意,yield* 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。
  其次,其它调用到遍历器的操作还有解构赋值、扩展操作符、其它任何接受数组作为参数的场合,如:
  • for...of
  • Array.from()
  • Map(), Set(), WeakMap(), WeakSet()(比如)
  • Promise.all()
  • Promise.race()
 
 
  一旦当你给你的结构部署了iterator接口,那么恭喜你,你可以使用for...of来遍历你的结构了!
 
  遍历器对象除了必须布置next方法以外,还有2个可选方法。return()和throw()。当一个解构在遍历的时候异常提前退出(比如break,continue或者出错)的时候,就会调用return方法,其次,return方法必须返回一个对象。
至于throw方法,则是用于抛出错误,Generator.prototype.throw这里不展开讲了,感兴趣的可以搜索一下。
 
  for of循环有很多优点,比如不像for...in一样只遍历键名(甚至包括原型链上的键),而且不像foreach不能跳出循环。并且for...of为各种数据结构提供了一个统一的遍历方法。所以,尽量使用它吧~
 
 
 
 
 
 
 
 

【前端】【javascript】es6中的遍历器接口Iterator的更多相关文章

  1. JavaScript ES6中,export与export default

    自述: 本来是对new Vue()和export default比较懵的,查了一下,发现我理解错了两者的关系,也没意识到export与export default的区别,先简单的记录一下基本概念,后续 ...

  2. JavaScript ES6中export、import与export default的用法和区别

    前言 相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在看他们之间的区别之前,我们先来看看它们的用法. ES6 import和export的用法 ...

  3. JavaScript ES6中export及export default的区别

    相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在JavaScript ES6中,export与export default均可用于导出常量.函 ...

  4. JavaScript ES6中export及export default的区别以及import的用法

    本文原创地址链接:http://blog.csdn.net/zhou_xiao_cheng/article/details/52759632,未经博主允许不得转载. 相信很多人都使用过export.e ...

  5. 彻底理解JavaScript ES6中的import和export

    0.前言 前端工程,在最早的时候是没有模块的概念的.随着前端工程的发展,前端开发也越来越规范化,更像是软件工程了.那么随之而来的,为了解决工程化的问题,就引入了模块的概念.但是在早期,因为ecmasc ...

  6. 现代JavaScript—ES6+中的Imports,Exports,Let,Const和Promise

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://www.freecodecamp.org/news/learn-modern-jav ...

  7. 【读书笔记】【深入理解ES6】#8-迭代器(Iterator)和生成器(Generator)

    循环语句的问题 var colors = ["red", "green", "blue"]; for (var i = 0, len = c ...

  8. ES6之遍历器(Iterator)

    什么是Iterator?他是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署上Iterator接口就可以完成遍历操作(PS:个人认为他的这个遍历就是c语言里面的指针),他的作用有 ...

  9. JavaScript ES6中export、export default、import用法和区别

    相信熟悉JS ES6的同学都知道export.export default是导出,import是导入的意思. 那么问题就来了, 1.import 导入要怎么用? 2.export.export def ...

随机推荐

  1. 小贝_php+redis简单实例

    php+redis简单实例 一.说明 因为redis是c/s架构.从这个角度上.不论什么符合redis的client要求的.都能够与redis进行通讯.官方提供了非常多的client. php在web ...

  2. 【BZOJ4026】dC Loves Number Theory 分解质因数+主席树

    [BZOJ4026]dC Loves Number Theory Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯竭的水题资源.    给 ...

  3. 记录-项目java项目框架搭建的一些问题(maven+spring+springmvc+mybatis)

    伴随着项目框架的落成后,本以为启动就能成功的,but.... 项目启动开始报错误1:java.lang.ClassNotFoundException: org.springframework.web. ...

  4. java拾遗2----XML解析(二) SAX解析

    XML解析之SAX解析: SAX解析器:SAXParser类同DOM一样也在javax.xml.parsers包下,此类的实例可以从 SAXParserFactory.newSAXParser() 方 ...

  5. Struts中类型转换踩的坑

    出现的异常: 当我输入的数据很大时候,转换后如上,这并不是我想要的, 出现问题的原因: Struts2对常用的数据类型如String.Integer.Double等都添加了转换器进行对应的转换操作. ...

  6. DDD开源框架

    DDD开源框架: ABP ENODE https://github.com/VirtoCommerce/vc-community APWorks https://github.com/daxnet/B ...

  7. nginx 基础配置详解

    #本文只对nginx的最基本配置项做一些解释,对于配置文件拆分管理,更详细的集群健康检查的几种方式,检查策略等在此不做详细解释了. #运行用户user nobody;#启动进程,通常设置成和cpu的数 ...

  8. SAP ATP邏輯可用性檢查

    [转http://tqmeng.blog.163.com/blog/static/169263916201162002414612/]SAP ATP邏輯可用性檢查1.可用性檢查群組OVZ2主要用於檢查 ...

  9. print函数详解及python打印99乘法表的不同方法

    首先你需要了解print的原型,并且要知道在python2和python3中print函数功能不同,不只是表现在后面带不带()一方面! 在python3中,通过help(print)可以得到print ...

  10. C#BackgroundWorker组件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...