本文实例讲述了ES6 Iterator遍历器原理,应用场景及相关常用知识拓展。分享给大家供大家参考,具体如下:
介绍Iterator之前先列举下js的表示数据集合结构的几种方式:
在es6之前有 Array , Object, es6新增了 map, set,当然用户也可以组合使用这几种数据结构,灵活存储数据。
但是当数据结构变得复杂后,怎样取到里面的数据就也相对复杂,这就需要有一种读取数据的统一的接口机制,来处理不同的数据结构。
1,为各种数据结构提供一种统一的,简单的访问接口;
2,使得数据结构的成员能够按照某种次序排列;
3,ES6提供了一种新的遍历循环(for......of.....),Iterator被for......of.....循环调用;
遍历器本质上是一种指针对象,指针对象上有next()方法,第几次调用就指向第几个成员
1,返回当前成员的信息
2,返回遍历是否结束
模拟实现Iterator
var it = makeIterator(['a', 'b']); it.next() // { value: "a", done: false } it.next() // { value: "b", done: false } it.next() // { value: undefined, done: true } function makeIterator(array) { var nextIndex = 0; return { next: function() { return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {value: undefined, done: true}; } }; }
使用Typescript
interface Iterable { [Symbol.iterator]() : Iterator, } interface Iterator { next(value?: any) : IterationResult, } interface IterationResult { value: any, done: boolean, }
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。
Symbol.iterator的本质:
1,Symbol.iterator本身是一个函数,对应当前数据结构默认的遍历器生成函数;
2,执行Symbol.iterator这个函数会返回一个遍历器。
实例:
const obj = { [Symbol.iterator] : function () { return { next: function () { return { value: 1, done: true }; } }; } }; //这样定义后对象就有了Iterator接口 //执行对象obj的symbol.iterator后,返回一个遍历器
具有原生iterator的数据结构:
Array , Map, Set, String, TypedArray, 函数的argulements对象,NodeList对象(节点对象);
数组iterator实例
let arr = ['a', 'b', 'c']; let iter = arr[Symbol.iterator](); iter.next() // { value: 'a', done: false } iter.next() // { value: 'b', done: false } iter.next() // { value: 'c', done: false } iter.next() // { value: undefined, done: true }
对象iterator接口实现
class RangeIterator { constructor(start, stop) { this.value = start; this.stop = stop; } [Symbol.iterator]() { return this; } next() { var value = this.value; if (value < this.stop) { this.value++; return {done: false, value: value}; } return {done: true, value: undefined}; } } function range(start, stop) { return new RangeIterator(start, stop); } for (var value of range(0, 3)) { console.log(value); // 0, 1, 2 }
注意:如果一个对象没有iterator接口,而其原型链上有Iterator接口,也可以通过继承而拥有该接口;
使用while循环遍历
var $iterator = ITERABLE[Symbol.iterator](); var $result = $iterator.next(); while (!$result.done) { var x = $result.value; // ... $result = $iterator.next(); }
基本概念基本就是这些,接下来看下使用场景
默认调用场景:
for....of...循环, 解构赋值, 扩展运算符, yield*关键字
ES6 借鉴 C++、Java、C# 和 Python 语言,引入了for...of循环,作为遍历所有数据结构的统一的方法
这里主要介绍下yield*,其余几个都比较好理解
yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
let generator = function* () { yield 1; yield* [2,3,4];//执行时默认遍历数组 yield 5; }; var iterator = generator(); iterator.next() // { value: 1, done: false } iterator.next() // { value: 2, done: false } iterator.next() // { value: 3, done: false } iterator.next() // { value: 4, done: false } iterator.next() // { value: 5, done: false } iterator.next() // { value: undefined, done: true }
其他场景:
由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口
知识拓展:
return方法在循环退出或者报错时调用
throw方法主要是配合 Generator 函数使用(详见generator)
在原有数据结构基础上计算生成的数据结构,例如Object,Map,Set,Array的entries(),keys(), value()方法生成的数据结构,默认具有iterator接口
常见:字符串,NodeList节点对象,参数arguments
1,并不是所有类似数组的对象都具有 Iterator 接口
2,对于类数组对象可以通过Array.From()将类数组对象转化为数组对象
3,for-of可以识别32 位 UTF-16 字符
for (let x of 'a\uD83D\uDC0A') { console.log(x); }
for循环,forEach循环,for...in...循环
forEach循环无法中途跳出
for...in循环有几个缺点(for...in循环主要是为遍历对象而设计的,不适用于遍历数组),
对于for...of...
参考:http://es6.ruanyifeng.com/
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
本文向大家介绍vue-router相关基础知识及工作原理,包括了vue-router相关基础知识及工作原理的使用技巧和注意事项,需要的朋友参考一下 前言 今天面试被问到 vue的动态路由,我竟然没有回答上来,感觉不是什么难得问题。好久没有看vue-router的文档,很多用的东西和概念没有对上。回来一看什么是动态路由就傻眼了。看来有必要把vue -router相关知识总结一下,好丢人的感觉。 单
本文向大家介绍Python装饰器实现方法及应用场景详解,包括了Python装饰器实现方法及应用场景详解的使用技巧和注意事项,需要的朋友参考一下 应用场景: 1、授权(Authorization) 装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中。这里是一个例子来使用基于装饰器的授权: 2.、日志(Logging
本文向大家介绍isinstance作用以及应用场景?相关面试题,主要包含被问及isinstance作用以及应用场景?时的应答技巧和注意事项,需要的朋友参考一下 isinstance(对象,类) 判断这个对象是不是这个类或者这个类的子类的实例化 应用场景:rest framework 认证的流程 scrapy-redis
本文向大家介绍metaclass作用?以及应用场景?相关面试题,主要包含被问及metaclass作用?以及应用场景?时的应答技巧和注意事项,需要的朋友参考一下 metaclass用来指定类是由谁创建的。 类的metaclass 默认是type。我们也可以指定类的metaclass值。在python3中
本文向大家介绍Bootstrap3 Grid system原理及应用详解,包括了Bootstrap3 Grid system原理及应用详解的使用技巧和注意事项,需要的朋友参考一下 刚开始用Bootstrap的格子系统写布局的时候遇到了这样一个问题: 我的页面中有这样一个布局 我希望当屏幕的宽度小于他们俩宽度之和的时候,右边的部分会掉下来,他们垂直摆放。 而我用col-xs-6的话,右边的盒子永远都
常用场景是围绕以场景分析为主,满足企业中市场、运营、产品等不同业务部门的不同角色,在使用通用的一些分析功能时,可以自定义添加常用场景;以达到在使用分析平台时,可以直接查看、分析特定的业务场景(例如:注册分析、渠道分析、开户分析等等)。 功能及使用 1.添加常用场景 你可以在通用分析整体、事件、漏斗使用分析时,可以把一些业务场景的分析,添加到「常用场景」分析中,添加后,之后在「常用场景」分析中可以直