当前位置: 首页 > news >正文

如何跳出forEach循环

介绍

相信所有的前端小伙伴对 forEach() 方法并不陌生,它实现了对数组的每个元素执行一次给定的函数。可在使用中,经常希望跟 for 一样,在循环过程中,某个判断成立后跳出这个循环。本期我们就将聊聊 forEach 的实现及使用,以及跳不出去的原因,还有跳出方案。

正文

循环对比

众所周知,for 循环跳出非常容易:

let arr = [...new Array(10).keys()]
for(let i = 0; i < arr.length;i++){
	console.log(`item:${arr[i]}`)
	if(arr[i]>5) break;
}

可是对于 forEach() 方法或许这点就让人失望了,它是从头走到底的,不仅 return 都是无效的,而且 break 还是直接报错;

为何无法跳出

为了了解无法跳出循环的原因,我们就简单手写一个 forEach 方法,来探查这个原因。
我们先来分析一下,语法和传参:

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
  • callback:数组中每个元素需要执行的回调函数
    • currentValue:当前元素的值。
    • index:当前元素的索引值。
    • array:当前所操作的数组。
  • thisArg:可选参数。当执行回调函数 callback 时,用作 this 的值。
   	 Array.prototype.myForEach = function(callback,self){
   	    let _arr = [...this];
   	    for(let i = 0;i<_arr.length;i++){
   	        callback.call(self,_arr[i],i,_arr)
   	    }
   	}

如你所见寥寥几句就可以实现出我们的 forEach 方法了,而且,由此可见,我们了解到它本身也是借用的 for 循环 来处理当前元素,执行回调方法,在这个方法里肯定是跳不出来的。那有什么办法能让回调函数中断呢?对,就是抛出异常。

实现跳出

现在我们就来用抛出异常的方式来完成这个跳出任务。

let arr = [...new Array(10).keys()];
try{
    arr.forEach(item=>{
        console.log(`item:${item}`)
        if(item>5) throw new Error("break");
    })
}catch(err){
    if(err.message === "break")	
        console.log("break success!")
    else 
        console.error(err)
}

我们这里用了抛出异常的方式直接让回调函数报错来实现,但是还要注意一点,最好还要传入一个异常错误的 message ,我这里定为 字符串信息break,因为我们在运行时还有可能报出别的错误,有了这个标识就能识别处理哪个是正常的跳出循环,哪个是真正的执行错误。

结语

其实不仅仅是 forEach() 方法,还有一个平时经常使用的 map() 方法也是大同小异的,可以用抛出异常来实现跳出循环的操作。但我们其实也完全可以使用 some() , every() 等方法来提前验证好,或者使用 findIndex() 去检测条件捕获索引后再进行二次遍历处理。

相关文章:

  • 大咖论道|银行核心系统国产分布式数据库选型思考
  • 简单5分钟,将lowcode低代码融入到你的中后台管理系统
  • token、cookie、session
  • 强大多云混合多K8S集群管理平台Rancher入门实战
  • 学习编程的第二十四天
  • 第五十一周总结——对象遍历方法
  • java计算机毕业设计民宿预订管理系统设计与实现源码+数据库+系统+lw文档+mybatis+运行部署
  • 渗透测试-微信小程序-公众号测试经验总结
  • innodb存储引擎学习–备份
  • 《nginx》二、nginx反向代理
  • FastAPI 学习之路(三十一)CORS(跨域资源共享)
  • pytorch数据增强
  • ROS1云课→14可视化交互
  • 学习处理Doxygen的xml输出
  • NDS教程
  • 2017年终总结、随想
  • Druid 在有赞的实践
  • Elasticsearch 参考指南(升级前重新索引)
  • flutter的key在widget list的作用以及必要性
  • IOS评论框不贴底(ios12新bug)
  • Java多线程(4):使用线程池执行定时任务
  • markdown编辑器简评
  • Objective-C 中关联引用的概念
  • Spark学习笔记之相关记录
  • 给新手的新浪微博 SDK 集成教程【一】
  • 排序(1):冒泡排序
  • 前端面试之闭包
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 再谈express与koa的对比
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • ${factoryList }后面有空格不影响
  • (+4)2.2UML建模图
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (四)模仿学习-完成后台管理页面查询
  • (算法二)滑动窗口
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • .bat批处理(一):@echo off
  • .gitignore文件---让git自动忽略指定文件
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .net 按比例显示图片的缩略图
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .NET构架之我见
  • .NET开源项目介绍及资源推荐:数据持久层
  • .net中生成excel后调整宽度
  • .php文件都打不开,打不开php文件怎么办
  • :如何用SQL脚本保存存储过程返回的结果集
  • @Autowired 与@Resource的区别