ECMAScript中迭代器的深入讲解

目录
  • 前言
  • 较早的迭代
  • 迭代器模式
  • 迭代器工厂函数
  • 迭代器协议
  • 写在最后

前言

许多初级前端开发者在往中级迈进的过程中,面试经常问到的一个就是迭代器和生成器,其实在开发中都用过,但是并不知道这是什么,或者有些许了解但并不够深入。那这篇文章就对这一部分开发者会有一定的帮助,讲清楚迭代器这玩意。

较早的迭代

迭代肯定知道,简单理解起来就是循环,在JavaScript 中,计数循环便是最简单的一种。示例:

for(let i = 0; i < 9; ++i){
	console.log("[ i ]", i);
}

迭代的基础就是循环,它包含几个必要条件:

  • 可以指定迭代的次数
  • 可以指定每次迭代执行的操作
  • 每次迭代都在下一次迭代开始前完成
  • 顺序都是事先定义好的

当需要循环遍历一个数组的时候,迭代是在一个有序的集合上进行的,「有序」即为数组中的所有元素都可以按照顺序从第一项到最后一项被遍历到。因为数组有确定的长度,以及每一项都可以通过索引下标去获取,也就是说可以通过索引去遍历整个数组。示例:

const arr = ["a", "b", "c"];

for(let i = 0; i < arr.length; ++i){
	console.log(arr[i]);
}

但是这种模式必须要事先知道使用的是什么数据结构,例如数组,如果换成其它数据类型,或者具有隐式顺序的数据结构,那么遍历的顺序就不可确定。

于是在 ES5 中新增了forEach()方法。示例:

const arr = ["a", "b", "c"];

arr.forEach(item=>{
	console.log(item);
});

这个方法就不用同数组索引去遍历和获取单项的取值,但无法标识迭代什么时候结束,因此仅适用于数组的遍历。为了解决这些问题,ES6 之后,JavaScript 支持了迭代器模式。

迭代器模式

迭代器模式是一种非常抽象的说法,可以把它理解成数组或者集合这一类的对象,它们的元素是有限的,且互相独立无歧义。引用红宝书的解释,即为:

迭代器模式(特别是在ECMAScript这个语境下)描述了一个方案,即可以把有些结构称为“可迭代对象”(iterable),因为它们实现了正式的Iterable接口,而且可以通过迭代器Iterator消费。

迭代器工厂函数

迭代器工厂函数,也就是 Symbol.iterator(),它是大部分内置类型都含有的默认属性,通过它暴露 Iterable 接口(可迭代协议),也就是说要想数据类型支持迭代,那么该类型必须支持可迭代协议。

ECMAScript 中规定暴露的默认迭代器,必须以“Symbol.iterator”作为键,返回一个新的迭代器。检查是否存在默认迭代器属性的方法也很简单。示例:

const obj = {};
const arr = ["a", "b", "c"];

console.log(obj[Symbol.iterator]); // underfined
console.log(arr[Symbol.iterator]); // f values() { [native code] }

console.log(arr[Symbol.iterator]()); // ArrayIterator {}

当然,我们实际开发中是不用显示调用迭代器工厂函数的,支持可迭代协议的数据类型会自动兼容接受可迭代对象的任何语言特性,例如当我们使用循环、for-of、解构、扩展操作符的时候,会自动在后台调用提供的可迭代对象的迭代器工厂函数,从而创建一个迭代器。

迭代器协议

迭代器协议约定迭代器是一种一次性使用的对象,当调用迭代器工厂函数后,返回一个next()方法,每一次迭代成功都会调用该方法,得知下一个迭代的值,如果不调用,则不确定迭代的当前位置。

next()方法返回一个对象,包含量属性:done和value,done 表示是否可以继续调用next()方法获取下一个值,意为是否「耗尽」,返回一个 Boolean 值; value 表示可迭代对象的下一个值。done 为 true 时,value 则为 underfined。done 为 false 时,则会继续调用下一个迭代。示例:

// 可迭代对象
let arr = ['foo', 'bar'];// 迭代器工厂函数
console.log(arr[Symbol.iterator]);// f values() { [native code] }

// 迭代器
let iter = arr[Symbol.iterator]();
console.log(iter); // ArrayIterator{}

// 执行迭代
console.log(iter.next()); // { done: false, value: 'foo' }
console.log(iter.next()); // { done: false, value: 'bar' }
console.log(iter.next()); // { done: true, value: undefined }

写在最后

通过迭代器协议,你可以实现一个自定义的迭代器,比如规定迭代器可以被迭代的次数,或者提前终止迭代。

到此这篇关于ECMAScript中迭代器的文章就介绍到这了,更多相关ECMAScript迭代器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • ECMAScript中迭代器的深入讲解

    目录 前言 较早的迭代 迭代器模式 迭代器工厂函数 迭代器协议 写在最后 前言 许多初级前端开发者在往中级迈进的过程中,面试经常问到的一个就是迭代器和生成器,其实在开发中都用过,但是并不知道这是什么,或者有些许了解但并不够深入.那这篇文章就对这一部分开发者会有一定的帮助,讲清楚迭代器这玩意. 较早的迭代 迭代肯定知道,简单理解起来就是循环,在JavaScript 中,计数循环便是最简单的一种.示例: for(let i = 0; i < 9; ++i){ console.log("[ i

  • 稳扎稳打学Python之容器 可迭代对象 迭代器 生成器专题讲解

    目录 一.容器 1.什么是容器? 二.可迭代对象 1.什么是可迭代对象? 三.迭代器 四.序列 五.列表推导式 六.生成器 1.生成器的第一种创建方法:生成器表达式 2.生成器的第二种创建方法:yield 七.小结 今天就来给大家讲讲Python中的容器.可迭代对象.迭代器和生成器这些难理解的概念,让你的Python基础更上一层楼! 一.容器 1.什么是容器? 在Python中,容器是把多种元素组织在一起的数据结构,容器中的元素就可以逐个迭代获取.说白了,它的作用就像它的名字一样:用来存放东西(

  • linux 中vim的用法讲解

    Vim 是 Linux 系统上的最著名的文本/代码编辑器,也是早年的 Vi 编辑器的加强版,而 gVim 则是其 Windows 版.它的最大特色是完全使用键盘命令进行编辑,脱离了鼠标操作虽然使得入门变得困难,但上手之后键盘流的各种巧妙组合操作却能带来极为大幅的效率提升. vim的命令的一些格式 1:vim xxx 直接打开一个xxx命名的vim文件,如果没有的话直接创建一个新的.默认光标定义到第一行 2:vim + xxx 打开光标并定义到最后一行 3:vim +num xxx 打开光标定义到

  • 《JavaScript高级程序设计》阅读笔记(三) ECMAScript中的引用类型

    2.8 引用类型 1.Object类 ECMAScript中的所有类都是由Object类继承而来. Object类具有下列属性: Constructor:对创建对象的函数的引用(指针),对于Object类,该指针指向原始的Object()函数 Prototype:对该对象的对象原型的引用. Object类还有几个方法: HasOwnProperty(property):判断对象是否有某个特定的属性.必须用字符串指定该属性值 IsPrototypeOf(object):判断该对象是否为另一个对象的

  • java求两个数中的大数(实例讲解)

    java中的max函数在Math中 应用如下: int a=34: int b=45: int ans=Math.max(34,45); 那么ans的值就是45. 以上这篇java求两个数中的大数(实例讲解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • JavaScript高级程序设计阅读笔记(五) ECMAScript中的运算符(一)

    2.9 运算符 2.9.1.一元运算符 一元运算符只有一个参数,即要操作的对象或值. 1.delete:删除对以前定义的对象属性或方法的引用,但此运算符不能删除开发者未定义的属性和方法.示例: 复制代码 代码如下: var o=new Object; o.name="Nicholas"; o.show=function(){ return "test"; }; console.log(o.name); //outpus Nicholas console.log(o.

  • Python 中迭代器与生成器实例详解

    Python 中迭代器与生成器实例详解 本文通过针对不同应用场景及其解决方案的方式,总结了Python中迭代器与生成器的一些相关知识,具体如下: 1.手动遍历迭代器 应用场景:想遍历一个可迭代对象中的所有元素,但是不想用for循环 解决方案:使用next()函数,并捕获StopIteration异常 def manual_iter(): with open('/etc/passwd') as f: try: while True: line=next(f) if line is None: br

  • python中迭代器(iterator)用法实例分析

    本文实例讲述了python中迭代器(iterator)用法.分享给大家供大家参考.具体如下: #--------------------------------------- # Name: iterators.py # Author: Kevin Harris # Last Modified: 03/11/04 # Description: This Python script demonstrates how to use iterators. #----------------------

  • vue父组件中获取子组件中的数据(实例讲解)

    如下所示: <FormItem label="上传头像" prop="image"> <uploadImg :width="150" :height="150" :name="'avatar'" size="150px*150px" ref="avatar"></uploadImg> </FormItem> <Fo

  • JavaScript高级程序设计 阅读笔记(七) ECMAScript中的语句

    if语句 语法: 复制代码 代码如下: if(condition){ statement1; } else{ statement2; } 迭代语句 1.do-while语句 语法: 复制代码 代码如下: do{ statement }while(expression); 2.while语句 语法: 复制代码 代码如下: while(expression){ statement } 3.for语句 语法: 复制代码 代码如下: for(initialization;expression;post-

随机推荐