详解JS前端使用迭代器和生成器原理及示例

yizhihongxing

标题:详解JS前端使用迭代器和生成器原理及示例

什么是迭代器

迭代器是一种设计模式,它提供了一种顺序访问聚合对象元素的方法,而不需要暴露对象的内部表示。迭代器可以分为内部迭代器和外部迭代器。在JavaScript中,数组就是一个内部迭代器。

内部迭代器: 它的迭代规则已经被提前规定,对于每一次迭代,外界没有任何变量参与。这样做的优点是内部迭代器的调用非常简单,外界不用关心迭代器的实现细节,只需要一次初始调用即可。

下面是一个内部迭代器的示例:

function forEach(arr, fn){
  for(var i = 0, l = arr.length; i < l; i++){
    fn(arr[i], i, arr);
  }
}

var arr = [1, 2, 3];

forEach(arr, function(item, index, array){
  console.log(item, index, array);
});

什么是生成器

生成器是ES6里面引入的一种迭代器,是一种更加灵活的迭代器,它可以动态产生迭代器的过程。生成器函数使用function *语法定义。它能够像一般函数一样使用return返回一个值并结束函数,也能够通过yield返回值并暂停函数执行,等待下一次调用时再继续执行。生成器在需要消耗大量时间的操作时,可以极大地提高效率和性能。

下面是一个生成器的示例:

function* gen(){
  console.log(1);
  yield;
  console.log(2);
  return 3;
}

const it = gen();
it.next(); // 输出1,执行到第一个yield
it.next(); // 输出2,执行到return,输出3,结束执行

迭代器和生成器的原理

迭代器的实现原理是利用闭包。每调用一次迭代器,都返回一个函数,在每次外部函数调用内部函数时,都会使得闭包中的状态改变,从而实现对下一次迭代的控制。

生成器的实现原理同样利用闭包。定义生成器函数时,会通过yield将生成器函数分割为若干个部分,每次执行next()方法时,都会继续执行生成器函数直至遇到下一个yield语句,返回结果或函数执行结束。生成器函数在执行时会暂停并保存其上下文,这样在需要恢复执行时可以继续执行。每次执行next()方法后,生成器函数都会从保存的上下文中恢复执行。

迭代器和生成器的使用示例

下面是一个使用ES6中生成器来实现斐波那契数列的示例:

function* fibonacci(){
  let prev = 1, cur = 1;
  while(true){
    yield cur;
    [prev, cur] = [cur, prev + cur]; //注意这里的解构赋值写法
  }
}

let it = fibonacci();

for(let i = 0; i < 10; i++){
  console.log(it.next().value);
}

下面是一个使用迭代器来实现数组去重的示例:

function unique(arr){
    const set = new Set();
    return function* (){
        for(const item of arr){
            if(!set.has(item)){
                set.add(item);
                yield item;
            }
        }
    }();
}

const arr = [1,2,2,3,3,4,4,4,5,5];
const it = unique(arr);

for(let item of it){
    console.log(item);  // 1 2 3 4 5
}

这个示例中,unique()函数返回一个生成器对象,进行去重操作。每次循环时,先判断当前元素是否在Set集合内,如果不在就把它加入集合,然后通过yield来输出这个元素。这个函数每返回一个新值,都会保存当前状态,下一次执行时,从上次暂停的地方继续执行。而使用for...of循环遍历生成器对象,使得整个过程更加简洁明了,易于理解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JS前端使用迭代器和生成器原理及示例 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • JavaScript双向链表实现LRU缓存算法的示例代码

    首先,我们需要了解下什么是双向链表和LRU缓存算法。 双向链表:每个节点有两个指针,一个指向其前驱节点,一个指向其后继节点。双向链表的优势在于可以快速对链表中的任意节点进行插入、删除和移动操作,时间复杂度均为O(1)。 LRU缓存算法:Least Recently Used,即最近最少使用。LRU缓存算法通过记录缓存中每个数据项的访问时间,当缓存空间满时,将…

    node js 2023年6月8日
    00
  • windows系统下简单nodejs安装及环境配置

    Windows系统下简单nodejs安装及环境配置攻略 安装Node.js 打开 Node.js 官网(https://nodejs.org/zh-cn/),选择 “Download” 下载 Node.js 安装包。 打开下载好的 Node.js 安装包,按照提示一步步安装即可。安装过程中注意选择 “Add to Path” 选项,它会自动将 Node.js…

    node js 2023年6月8日
    00
  • Nodejs模块载入运行原理

    一、Nodejs模块载入 Nodejs模块载入指的是当需要使用模块时,Nodejs会通过一定的方式找到对应的模块文件,载入这个模块,并在当前的上下文环境中运行该模块。 二、Nodejs模块化 Nodejs支持模块化编程,这意味着一个功能被拆分成多个文件,每个文件都是一个模块,在程序中需要使用该功能时,只需要加载这个模块即可,避免了单一文件过大、难于维护的问题…

    node js 2023年6月8日
    00
  • Node.js实现前端后端数据传输加密解密

    下面是详细讲解“Node.js实现前端后端数据传输加密解密”的完整攻略: 1. 确定加密方案 要实现前端后端数据传输加密解密,需要确定一个加密方案。推荐使用AES加密算法,它是一种对称加密算法,既可以用于加密数据,也可以用于解密数据。同时,它的加解密速度也较快,且安全性较高。 2. 安装crypto模块 Node.js自带了crypto模块,可以用于进行加密…

    node js 2023年6月8日
    00
  • Spring Boot 与 Vue.js 整合流程

    下面是关于“Spring Boot与Vue.js整合流程”的完整攻略: 前言 Spring Boot是一个快速开发Web应用的工具,Vue.js是一个流行的前端框架,将它们整合可以帮你快速开发出高效的Web应用。本文将介绍如何使用Spring Boot和Vue.js创建一个完整的Web应用程序。 环境准备 在开始之前,你需要确保你的电脑上已经安装了以下软件:…

    node js 2023年6月8日
    00
  • 手机Web APP如何实现分享多平台功能

    分享是手机Web APP中常见的功能之一,让用户可以将自己喜欢的内容快速分享到自己的社交媒体账号上,从而实现增加用户粘性、提升用户体验的效果。实现多平台分享,可以让用户同时分享到不同的社交媒体平台,扩大传播范围,提高品牌曝光率。下面是实现手机Web APP多平台分享功能的完整攻略。 1. 获取分享渠道的授权 在实现多平台分享之前,需要先获取对应社交媒体平台的…

    node js 2023年6月8日
    00
  • 详解用Node.js写一个简单的命令行工具

    那么我们来详细讲解一下如何用Node.js写一个简单的命令行工具。可以按照以下步骤进行操作: 第一步:创建一个新的Node.js项目 首先,需要创建一个新的Node.js项目。在命令行中,可以使用以下命令来创建一个新的项目: mkdir my-cli-tool cd my-cli-tool npm init 这将会让你进入一个交互式命令行,你需要回答一些问题…

    node js 2023年6月8日
    00
  • 了不起的node.js读书笔记之例程分析

    针对“了不起的node.js读书笔记之例程分析”的完整攻略,我可以为您提供以下内容: 标题 “了不起的node.js读书笔记之例程分析”完整攻略 前言 对于初学者而言,node.js入门的确是需要花费一定的时间和精力,因此,笔者为了方便初学者的学习,将自己的学习过程与心得体会进行了总结,并在此分享给大家,希望对大家的学习有所帮助。 示例一:使用Express…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部