【JavaScript面试】数组的forEach()方法总结

本文详细介绍了JavaScript数组的forEach方法,包括其语法特点、与for循环的区别以及性能比较。forEach提供了简洁的遍历方式,但不支持break和continue,无法直接删除自身元素。在性能上,for循环通常优于forEach。此外,还探讨了for...in和for...of的区别。
摘要由CSDN通过智能技术生成

前言

JavaScript数组的 forEach()方法总结。

语法

array.forEach(function(currentValue, index, arr), thisValue)
  • currentValue (这是一个必须属性)表示当前元素
  • index (可选)表示当前元素的索引值
  • arr (可选)表示当前元素所属的数组对象
  • thisValue 这个是一个可选参数

特点

  • 便利的时候更加简洁,效率和for循环相同,不用关心集合下标的问题,减少了出错的概率。
  • 没有返回值
  • 不能使用break中断循环,不能使用return返回到外层函数
var arr = [1, 2, 3];
var newarr=arr.forEach(function(curr, index, arr) {
            console.log(curr, index, arr)
      })
 console.log(newarr)
输出结果:
1 0 [1, 2, 3]
2 1 [1, 2, 3]
3 2 [1, 2, 3]
undefined

在这里插入图片描述

一般面试问题

有了for循环,为什么还要forEach?

这个问题的核心在于问for循环和forEach()的区别?我们可以从三个方面来回答这个问题。

1. for循环和forEach的本质区别?

forEach 其实是一个迭代器,他与 for 循环本质上的区别是 forEach 是负责遍历(Array Set Map)可迭代对象的,而 for 循环是一种循环机制,只是能通过它遍历出数组。
forEach是ES5提出的,挂载在可迭代对象原型上的方法,例如Array Set Map。
forEach是一个迭代器,负责遍历可迭代对象。
(迭代器是一种特殊对象。ES6规范中它的标志是返回对象的next() 方法,迭代行为判断在done之中。在不暴露内部表示的情况下,迭代器实现了遍历。)

      //本质区别 forEach迭代器
        let arr = [1, 2, 3, 4] //可迭代对象
        let iterator = arr[Symbol.iterator]() //调用Symbol.iterator 后生成了迭代器对象
        console.log(iterator.next()); // {value: 1, done: false} 访问迭代器对象的next方法
        console.log(iterator.next()); // {value: 2, done: false}
        console.log(iterator.next()); // {value: 3, done: false}
        console.log(iterator.next()); // {value: 4, done: false}
        console.log(iterator.next()); // {value: undefined, done: true}

在这里插入图片描述

2. for循环和forEach的语法区别?
  • 参数
array.forEach(function(currentValue, index, arr), thisValue)
 let arr2 = [1, 2, 3, 4];
        let person = {
            name: '技术直男'
        };
        arr2.forEach(function(self, index, arr) {
            console.log(`当前元素为${self}索引为${index},属于数组${arr}`);
            console.log(this.name += '---真帅');
        }, person)
        //当前的this指向的是person

结果为:
在这里插入图片描述

  • for和forEach 的中断
    • 在js中有break return continue对函数进行中断或跳出循环的操作,
    • 我们在 for循环中会用到一 些中断行为,对于优化数组遍历查找是很好的
    • 但由于forEach属于迭代器, 只能按序依次遍历完成,所以不支持上述的中断行为。
        let arr3 = [1, 2, 3, 4];
        for (let i = 0; i < arr3.length; i++) {
            if (arr3[i] === 2) {
                break;
            };
            console.log('for中断', arr3[i]);
        };

结果是:
在这里插入图片描述

let arr3 = [1, 2, 3, 4];
arr3.forEach((self, index) => {
            console.log('forEach中断', self);
            if (self === 2) {
                // break; //报错
                return; //会继续循环
                // continue; //报错
            };
        });

当其为break时结果报错,如下图:
在这里插入图片描述

当其为return时虽然没有报错,但是会继续循环,没有达到跳出循环的作用。如下图:
在这里插入图片描述

当其为continue时会报错,如下图:
在这里插入图片描述

那么问题来了:
forEach不能使用break和continue这两个关键字,本身无法跳出循环,也不能像普通for循环一样使用return跳出,必须遍历所有的数据才能结束。
我们如何跳出forEach中的循环呢?可以用try…catch…的方法

try…catch…完整语法

try {
    tryCode - 尝试执行的代码块
}
catch(error) {
    catchCode - 捕获错误的代码块
}
finally {
    finallyCode - 无论 try / catch 结果如何都会执行的代码块
}
  let arr3 = [1, 2, 3, 4];
        try {
            arr3.forEach(function(self, index) {
                //跳出条件
                if (self === 2) {
                    throw new Error("LoopTerminates");
                }
                //do something
                console.log('forEach中断', self);
            });
        } catch (e) {
            if (e.message !== "LoopTerminates") throw e;
        };

在这里插入图片描述
达到了和for循环一样的效果。

  • forEach 删除自身元素,index不可被重置
    在forEach 中我们无法控制index 的值,它只会无脑的自增直至大于数组的length 跳出循环。所以也无法删除自身进行index
let arr4 = [1, 2, 3, 4]
        arr4.forEach((item, index) => {
            // console. log(item); //1 2 3 4
            index++;
        });

index不会随着函数体内部对它的增减而发生变化。在实际开发中,遍历数组同时删除某项的操作十分常见,在使用forEach删除时要注意。

  • forEach的循环起点只能为0不能进行人为干预,而for循环不同
3. for循环和forEach的性能区别?
  • 性能比较: for > forEach > map
  • |在chrome 62和Node. js v9.1.0环境下:
    for循环比forEach 快1倍,forEach比map 快20%左右。
    原因分析for: for循环没有额外的函数调用栈和上下文,所以它的实现最为简单。
    forEach:对于forEach来说, 它的函数签名中包含了参数和上下文,所以性能会低于for 循环。
    map: map最慢的原因是因为map会返回一个新的数组,数组的创建和赋值会导致分配内存空间,因此会带来较大的性能开销。

以上详细可以看链接

for, forEach,for in,for of区别

for in(大部分用于对象):
用于循环遍历数组或对象属性

特性:
可以遍历数组的键名,遍历对象简洁方便

   let person={name:"小白",age:28,city:"北京"}
   let text=""
   for (let i in person){
      text+=person[i]
   }
   输出结果为:小白28北京
//其次在尝试一些数组
   let arry=[1,2,3,4,5]
   for (let i in arry){
        console.log(arry[i])
    }
//能输出出来,证明也是可以的

for of(不能遍历对象):
特性:

  1. (可遍历map,object,array,set string等)用来遍历数据,比如组中的值
  2. 避免了for in的所有缺点,可以使用break,continue和return,不仅支持数组的遍历,还可以遍历类似数组的对象。
   let arr=["nick","freddy","mike","james"];
    for (let item of arr){
        console.log(item)
    }
//暑促结果为nice freddy mike james
//遍历对象
   let person={name:"老王",age:23,city:"唐山"}
   for (let item of person){
        console.log(item)
    }
//我们发现它是不可以的
//但是它和forEach有个解决方法,结尾介绍

总结:

  • forEach 遍历列表值,不能使用 break 语句或使用 return 语句
  • for in 遍历对象键值(key),或者数组下标,不推荐循环一个数组
  • for of 遍历列表值,允许遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代的数据结构等.在 ES6 中引入的 for of 循环,以替代 for in 和 forEach() ,并支持新的迭代协议。
  • for in循环出的是key,for of循环出的是value;
  • for of是ES6新引入的特性。修复了ES5的for in的不足;
  • for of不能循环普通的对象,需要通过和Object.keys()搭配使用。
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵有千堆雪与长街

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值