JS面试题之forEach能否跳出循环详解

 更新时间:2021年06月11日 14:39:26   作者:茶无味的一天  
js中经常会使用foreach这个方法来遍历数组,这篇文章主要给大家介绍了关于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跳出循环内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 前端如何利用CryptoJS实现数据信息的加密详解

    前端如何利用CryptoJS实现数据信息的加密详解

    这篇文章主要给大家介绍了关于前端如何利用CryptoJS实现数据信息加密的相关资料,前端解密解密工具Cryptojs提供了前端加密解密的工作,包括常用的MD5、BASE64、SHA1、AES等加密解密方法,需要的朋友可以参考下
    2023-11-11
  • js调试工具 Javascript Debug Toolkit 2.0.0版本发布

    js调试工具 Javascript Debug Toolkit 2.0.0版本发布

    Javascript Debug Toolkit是一个可以跨浏览器调试javascript的开源项目,支持在IE,FIREFOX,SAFARI,CHROME等浏览器中调试javascript。2.0.0版本做了较大变动,增加以下功能
    2008-12-12
  • javascript基本数据类型及类型检测常用方法小结

    javascript基本数据类型及类型检测常用方法小结

    这篇文章主要介绍了javascript基本数据类型及类型检测常用方法,总结分析了javascript的基本数据类型与类型检测的常用操作方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-12-12
  • JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法

    JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法

    这篇文章主要介绍了JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法,详细分析了弹出遮罩层效果的实现方法以及完整的实例代码,需要的朋友可以参考下
    2014-12-12
  • 多种方法实现JS动态添加事件

    多种方法实现JS动态添加事件

    JS动态添加事件的方法有很多,我们可以使用setAttribute、attachEvent 和 addEventListener等等,感兴趣的朋友可以参考下
    2013-11-11
  • JS组件Bootstrap dropdown组件扩展hover事件

    JS组件Bootstrap dropdown组件扩展hover事件

    bootstrap的下拉组件,需要点击click时,方可展示下拉列表。因此对于喜欢简单少操作的大家来说,点击一下多少带来不便,因此,引入hover监听,鼠标经过自动展示下拉框。这篇文章主要介绍了JS组件Bootstrap dropdown组件扩展hover事件,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • 详解uniapp页面跳转URL传参大坑

    详解uniapp页面跳转URL传参大坑

    本文主要介绍了详解uniapp页面跳转URL传参大坑,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • JavaScript实现的鼠标跟随特效示例【2则实例】

    JavaScript实现的鼠标跟随特效示例【2则实例】

    这篇文章主要介绍了JavaScript实现的鼠标跟随特效,结合2则实例形式分析了javascript针对鼠标事件的响应、计算、处理及页面元素动态操作相关实现技巧,需要的朋友可以参考下
    2018-12-12
  • 一个加载js文件的小脚本

    一个加载js文件的小脚本

    一个加载js文件的小脚本...
    2007-06-06
  • element el-input 删除边框的实现

    element el-input 删除边框的实现

    本文主要介绍了element el-input 删除边框的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04

最新评论