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

标题:详解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日

相关文章

  • 二叉树的非递归后序遍历算法实例详解

    二叉树的非递归后序遍历算法实例详解 二叉树的后序遍历是先遍历左子树,再遍历右子树,最后遍历根节点的顺序。使用递归方式实现比较简单,但是非递归方式实现却有一定难度。 本文将详细讲解如何使用非递归方式实现二叉树的后序遍历,并提供相应的示例说明。 算法思路 可以使用两个栈来实现二叉树的后序遍历。 首先将根节点压入栈A中,然后从栈A中弹出一个节点,将该节点压入栈B中…

    node js 2023年6月8日
    00
  • nodejs模块系统源码分析

    来一篇关于 “nodejs模块系统源码分析” 的完整攻略吧! 什么是模块 总体来说,在Node.js中,每个文件都被视为一个模块,而模块是 Node.js 的核心概念之一。 模块系统是 Node.js 的一个重要组成部分,它是 Node.js 的一个基本特性。从它的名称我们可以知道,模块系统有助于将一个程序分解为更小、更易于维护的部分,这可以让开发者更容易地…

    node js 2023年6月8日
    00
  • 新入门node.js必须要知道的概念(必看篇)

    下面来详细讲解“新入门node.js必须要知道的概念(必看篇)”的攻略。 标题 1. Node.js是什么 Node.js是由Ryan Dahl于2009年开发,基于Chrome V8引擎的JavaScript运行环境,使得JavaScript可以脱离浏览器运行在服务器端,提高了服务器JavaScript的开发效率,同时具备异步、事件驱动等特点,适合编写高并…

    node js 2023年6月8日
    00
  • 解决Node.js使用MySQL出现connect ECONNREFUSED 127.0.0.1:3306的问题

    当我们使用Node.js连接MySQL数据库时,有可能会出现connect ECONNREFUSED 127.0.0.1:3306的错误。这种错误通常是由于MySQL服务未启动、端口被占用、权限问题等原因引起的。接下来我将详细介绍如何解决这个问题。 问题分析 当我们使用Node.js连接MySQL数据库时,通常使用第三方库,如mysql、mysql2等。这些…

    node js 2023年6月8日
    00
  • node.js实现登录注册页面

    下面是详细讲解“node.js实现登录注册页面”的完整攻略。 1. 环境搭建 首先需要安装Node.js运行环境和npm包管理器,可以到Node.js官网下载并安装。 安装完成后,进入命令行工具,使用npm安装Express框架和相关的模块: npm install express express-session express-validator body…

    node js 2023年6月8日
    00
  • js 获取(接收)地址栏参数值的方法

    获取地址栏参数值是前端开发中常见的操作,JavaScript 提供了多种方法实现这个功能。下面是两种比较常用的方法: 方法一:使用 URLSearchParams URLSearchParams 是一个 Web API,可以方便地操纵 URL 的查询参数。在大部分浏览器上都有支持。 首先,我们可以通过 location.search 获取 URL 查询参数。…

    node js 2023年6月8日
    00
  • npm ERR! code 128的错误问题解决方法

    下面是“npm ERR! code 128的错误问题解决方法”的完整攻略。 问题描述 在使用npm安装/更新模块时,有时会遇到如下错误: npm ERR! code 128 npm ERR! Command failed: git clone –depth=1 -q https://github.com/xxx/xxx.git /Users/xxx/.np…

    node js 2023年6月8日
    00
  • webpack+vue.js快速入门教程

    webpack+vue.js快速入门教程 本教程旨在介绍如何在项目中使用 webpack 和 Vue.js。本教程假设你已经了解如何使用基本的 HTML、CSS 和 JavaScript。 1. 安装 Node.js 和 npm Node.js 和 npm 是安装和使用 webpack 的必要条件。 安装 Node.js 和 npm,请参考官方文档:http…

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