深入理解for,foreach,map的区别

如果你已经有使用JavaScript的经验,那你可能已经知道这两个看似相同的方法,深入解释了js中比较容易混淆的几种方法,重点在讲foreach和map 1. for方法

js for (语句1; 语句2; 语句3){ 被执行的代码块 } 语句1 (代码块)开始前执行 语句2 定义运行循环(代码块)的条件 语句3 在循环(代码块)已被执行之后执行

css 复制代码
一般写法如下:

```js
for(var i = 0;i< arr.length;i++) {
}

这就是一个常见的,正序循环的for循环。这样写的缺点大家都明白:每次都从arr里取length与i来对比,浪费性能(而且,要是arr的长度是动态变化的,就会比较麻烦)。改进这个循环的办法是用变量保存arr.length

js 复制代码
for(var i = 0, len = arr.length;i< len;i++) {
}

这样比第一种可以略微提升点性能,要是数组长,可以提升更多。 不过这样写就多了个变量,且这个变量只在用来与i对比的时候有用,看着有点鸡肋。 如果循环顺序对你不重要,那你可以尝试倒序循环:

js 复制代码
for (var i = arr.length - 1; i >= 0; i--) {
}

注意语句2为定义运行循环的条件,第一个满足i>=0即可,第二个运行i-- ,并且只要 i 是真值,循环就会继续 ,所以i的开始值为arr.length-1

最后总结下提高for循环性能的要点: 1,适时break!不需要遍历全部的就要加跳出条件! 2,不要在for循环体里声明变量(建议一次var,多次赋值) 3,数组长度缓存,尽量少变量

2.map方法

js 复制代码
 //值类型,不改变原数组,形成新的数组
 let valueArr = [11, 22, 33];
 let newArray = valueArr.map(item => item * 2);
 console.log(valueArr, newArray);  //[11,22,33]   [22,44,66]

 //引用类型,改变原数组
 let referArr = [{ width: 100 }, { width: 200 }];
 referArr.map(item => item.editable = true);   
 console.log(referArr)  //[{width:100,editable:true},{width:200,eidtable:true}]

3.forEach方法

js 复制代码
 //值类型,不改变原数组,返回值undefined
 let valueArr = [11, 22, 33];
 let newArray = valueArr.forEach(item => item * 2);
 console.log(valueArr, newArray);  //[11,22,33]   undefined

 //若要改变值,则需配合index来使用
 let newArr1 = valueArr.forEach((item, index) => {
      valueArr[index] = item * 2;
 });
 console.log(valueArr, newArray);  //[22,44,66]   undefined

 //引用类型,改变原数组
 let referArr = [{ width: 100 }, { width: 200 }];
 referArr.forEach(item => item.editable = true);   
 console.log(referArr)  //[{width:100,editable:true},{width:200,eidtable:true}]

注意点: 无论用forEach还是map遍历数组,用return来终止后面的语句是无效的,es6的forEach/map循环只能通过return中断当次循环

3.forEach 和 map 的共同点

  • 都是循环遍历数组中的每一项
  • 每一次执行匿名函数都支持三个参数,数组中的当前项item,当前项的索引index,原始数组input
  • 匿名函数中的this都是指window
  • 只能遍历数组

能用forEach()做到循环的,map()同样也可以做到循环。反过来也是如此。

4.差异点 1.map

有返回值,可以return出来一个length和原数组一致的数组(内容可能包含undefined、null等)

js 复制代码
const array = [12,24,27,23,26];  
const res = array.map((item,index,input) => {  
       return item*10;   
})  
console.log(res); // [120,240,270,230,260]
console.log(array); // [12,24,27,23,26]不变
  • 参数:item数组中的当前项,index当前项的索引,input原始数组
  • 区别:map的回调函数中支持return返回值,return的是一个数组,相当于把数组中的这一项进行改变(并不影响原来的数组,只是相当于把原数组克隆了一份,把克隆这一份的数组中的对应项改变了 );

2.forEach

没有返回值,返回结果为undefined

js 复制代码
const array = [12,24,27,23,26];  
const res = array.forEach((item,index,input) => {  
       return input[index] = item*10;   
})  
console.log(res); // undefined
console.log(array); // [120,240,270,230,260]原数组修改为变动后
  • 参数:item数组中的当前项,index当前项的索引,input原始数组;
  • 数组中有几项,那么传递进去的匿名回调函数就需要执行几次
  • 理论上这个方式是没有返回值的,只是遍历数组中的每一项,不对原来数组进行修改,但是可以自己通过数组的索引来修改原来的数组

3.尝试使用map循环,通过索引进行修改原数组值

在没有返回值的情况下,执行map函数,通过修改索引的方式进行修改原数组

js 复制代码
*const* array = [12,24,27,23,26]; 
const res = array.map((item,index,input) => { 
       input[index] = item*10; 
}) 
console.log(res);
console.log(array); 

通过以上代码,能够看到返回的结果长度仍然和原数组一致,但由于代码中没有执行return,则为undefined,而由于我们通过索引进行修改了匿名函数第三个参数,则导致原数组值也发生变化

总结:

  1. 都是用来遍历数组,forEach和map会为数组中每个元素执行回调函数。
  2. for循环是在确定数组的长度下使用,continue终止当前循环,break终止整个循环。
  3. map方法可以链式编程,但需要return。
  4. map:若数组的类型为值类型,则产生新的数组;若数组的类型为引用类型,则会改变原数组。
  5. forEach的基本原理就是for循环,返回值为undefined。
  6. forEach:若数组的类型为值类型,则不会改变原数组,若想改变原数组通过index这个参数来改变;若数组的类型为引用类型,则会改变原数组
  7. forEach()方法不会返回执行结果,而是undefined。forEach() 被调用时,不会改变原数组,也就是调用它的数组(尽管 callback 函数在被调用时可能会改变原数组)。
  8. map()方法会分配内存空间存储新数组并返回,map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)。
相关推荐
kyle~5 分钟前
Swagger ---基于 描述文件 生成 交互式API文档 的工具
前端·后端·规格说明书·说明文档
meilindehuzi_a7 小时前
从零理解并实现 RAG:用 LangChain.js 构建语义检索问答系统
开发语言·javascript·langchain
世界哪有真情9 小时前
拿人类意识卡 AI?等于用 bug 验收正式产品
前端·人工智能·后端
鱼樱前端9 小时前
别再自己拼凑了!这款 Vue 3.5+ 严肃产品级组件库,把 AI 对话、工作流和复杂数据全包了!
javascript·vue.js·github
Listen·Rain9 小时前
Vue3:setup详解
前端·javascript·vue.js
Patrick_Wilson10 小时前
修好 bug 只是开始:一次由监控需求反向重构日志结构的复盘
前端·监控·数据可视化
kyriewen10 小时前
面试官让我优化一个卡死的表格,我打开 Claude 五秒重写,他放下咖啡问我要不要来当组长
前端·javascript·面试
小粉粉hhh11 小时前
React(二)——dom、组件间通信、useEffect
前端·javascript·react.js
Csvn11 小时前
🤖 AI 生成前端代码的 5 个典型翻车现场及修复指南
前端
IT_陈寒12 小时前
SpringBoot自动装配坑了我一天,原来问题出在这
前端·人工智能·后端