jsforeach语句(JS面试题之forEach能否跳出循环详解)
jsforeach语句
JS面试题之forEach能否跳出循环详解当年懵懂无知的我被问到这个问题时,脑袋一片空白,当然也没答对,一直以来我对forEach都有一种错误的理解,由于它比原始的for循环简洁许多,导致我一度认为那是为了方便书写所创造出来的语法糖,在业务中也经常使用,但从没考虑过这种方式存在的问题。
forEach使用说明
参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach?v=example
arr.forEach(function callback(currentValue, index, array) { //your iterator }[, thisArg]);
- currentValue --- 当前处理的元素
- index --- 当前处理元素的索引
- array ---forEach应用的数组
有一段提示写到了在forEach中break和return的用法。原文如下:
There is no way to stop or break a forEach()loop other than by throwing an exception. If you need such behavior, theforEach()method is the wrong tool. Use a plain loop instead. If you are testing the array elements for a predicate and need a Boolean return value, you can useevery() or
some() instead. If available, the new methodsfind() or findIndex() can be used for early termination upon true predicates as well.
意思就是说在forEach中使用break和return是错误的,如果希望使用break或者return请使用every或者some函数。
那么回到标题,首先forEach是不能使用任何手段跳出循环的,为什么呢?我们知道forEach接收一个函数,它一般有两个参数,第一个是循环的当前元素,第二个是该元素对应的下标,我们手动实现一下:
Array.prototype.myForEach = function (fn) { for (let i = 0; i < this.length; i++) { fn(this[i], i, this); } }
forEach是不是真的这么实现我无从考究,但是以上这个简单的伪代码确实满足forEach的特性,而且也很明显就是不能跳出循环,因为你根本没有办法操作到真正的for循环体。
后来经过查阅文档,发现官方对forEach的定义根本不是我认为的语法糖,它的标准说法是forEach为每个数组元素执行一次你所提供的函数。到这里我的思路逐渐明朗,官方文档也有这么一段话:
除抛出异常之外,没有其他方法可以停止或中断循环。如果您需要这种行为,则该forEach()方法是错误的工具。
使用抛出异常来跳出foreach循环
let arr = [0, 1, "stop", 3, 4]; try { arr.forEach(element => { if (element === "stop") { throw new Error("forEachBreak"); } console.log(element); // 输出 0 1 后面不输出 }); } catch (e) { console.log(e.message); // forEachBreak };
当然,使用try-catch包裹时,当循环体过大性能会随之下降,这是无法避免的,所以抛出异常并不是解决forEach问题的银弹,我们回归到开头写的那段伪代码,我们对它进行一些优化,在真正的for循环中加入对传入函数的判断:
Array.prototype.forEach = function (fn) { for (let i = 0; i < this.length; i++) { let ret = fn(this[i], i, this); if (typeof ret !== "undefined" && (ret == null || ret == false)) break; } }
这样的话自然就能根据return值来进行循环跳出啦:
let arr = [0, 1, "stop", 3, 4]; arr.forEach(element => { if (element === 'stop') return false console.log(element); // 输出 0 1 后面不输出 }); console.log('return即为continue:'); arr.forEach(element => { if (element === 'stop') return console.log(element); // 0 1 3 4 });
文档中还提到forEach需要一个同步函数,也就是说在使用异步函数或Promise作为回调时会发生预期以外的结果,所以forEach还是需要慎用或者不要使用,当然这并不意味着项目开发中要一直用简单的for循环去完成一切事情,我们可以在遍历数组时使用for..of..,在遍历对象时使用for..in..,而官方也在forEach文档下列举了其它一些工具函数:
Array.prototype.find() Array.prototype.findIndex() Array.prototype.map() Array.prototype.filter() Array.prototype.every() Array.prototype.some()
根据不同的业务场景,选择使用对应的工具函数来更有效地处理业务逻辑,至于forEach,我想就从此相忘于江湖吧。
总结
到此这篇关于JS面试题之forEach能否跳出循环的文章就介绍到这了,更多相关JS forEach跳出循环内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
- js宏任务都有哪些(JavaScript 操作宏任务与微任务)
- nodejs部署上传文件(node.js使用express-fileupload中间件实现文件上传)
- js实现string.format 字符串占位符
- 详解JS中你不知道的各种循环测速(详解JS中你不知道的各种循环测速)
- js怎么转拼音(js实现中文转拼音的完整步骤记录)
- linux用nvm安装nodejs(nodejs管理工具nvm安装过程详解)
- js日历图片(js实现简单日历效果)
- js如何实现定时器功能(js实现0ms延时定时器的几种方式)
- 最全js面试题(JavaScript必看的10道面试题总结推荐)
- js时间日期处理
- js 原生事件代理(如何利用原生JS实现触摸滑动监听事件)
- js页面跳转的几种代码
- js基础入门到高级教程(浅谈如何循序渐进的学好JS)
- JS匿名函数的用法
- laravel-admin代码执行流程(解决laravel-admin 自己新建页面里 js 需要刷新一次的问题)
- vue 富文本图片上传(vue.js云存储实现图片上传功能)
- 0 1 岁婴儿最强作息指南,照着做养出天使宝宝(01岁婴儿最强作息指南)
- 沪上这16所高校 萌新 礼包开箱 哪一款让你心动(沪上这16所高校萌新)
- 她救了被绑架的他,而这一切竟是一场阴谋...(她救了被绑架的他)
- 冬季养殖这6种阴生植物,方便又好养,你家有么(冬季养殖这6种阴生植物)
- 阴生植物为什么不怕照不到阳光(阴生植物为什么不怕照不到阳光)
- 阴生环境 耐阴地被植物,你知道哪些(阴生环境耐阴地被植物)
热门推荐
- sqlserver2012卸载工具(Windows下SQL Serever 2012彻底卸载删除教程)
- 数据化网络流量管理(适合云主机用户使用的流量监控软件)
- nginx状态查询(使用goaccess分析nginx日志的详细方法)
- 404页面如何设置
- dedecms默认模板目录(DEDECMS 5.7 将data目录迁移后,网站地图无法打开和更新的解决方法)
- 使用vue-cli构建electron项目(MAC+PyCharm+Flask+Vue.js搭建系统)
- vue通过什么获取dom(vue异步更新dom的实现浅析)
- mysql数据库使用规则(mysql数据库基本语法及操作大全)
- amaze ui使用教程(Amaze UI 文件选择域的示例代码)
- win7iis服务器的安装与配置(Win7怎么装IIS 安装IIS具体方法安装教程)