深入理解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 执行时改变原数组)。
相关推荐
GDAL3 分钟前
HTML 中的 Canvas 样式设置全解
javascript
m0_528723818 分钟前
HTML中,title和h1标签的区别是什么?
前端·html
Dark_programmer9 分钟前
html - - - - - modal弹窗出现时,页面怎么能限制滚动
前端·html
GDAL14 分钟前
HTML Canvas clip 深入全面讲解
前端·javascript·canvas
禾苗种树15 分钟前
在 Vue 3 中使用 ECharts 制作多 Y 轴折线图时,若希望 **Y 轴颜色自动匹配折线颜色**且无需手动干预,可以通过以下步骤实现:
前端·vue.js·echarts
GISer_Jing20 分钟前
Javascript排序算法(冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序)详解
javascript·算法·排序算法
贵州数擎科技有限公司37 分钟前
使用 Three.js 实现流光特效
前端·webgl
JustHappy39 分钟前
「我们一起做组件库🌻」做个面包屑🥖,Vue的依赖注入实战💉(VersakitUI开发实录)
前端·javascript·github
拉不动的猪1 小时前
刷刷题16
前端·javascript·面试
kiramario1 小时前
【结束】JS如何不通过input的onInputFileChange使用本地mp4文件并播放,nextjs下放入public文件的视频用video标签无法打开
开发语言·javascript·音视频