深入理解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 执行时改变原数组)。
相关推荐
Bingo_BIG3 分钟前
uni-app vue3 常用页面 组合式api方式
前端·javascript·uni-app
无限大.7 分钟前
基于 HTML5 Canvas 制作一个精美的 2048 小游戏--day2
前端·html·html5
索然无味io37 分钟前
PHP基础--流程控制
前端·笔记·后端·学习·web安全·网络安全·php
新生派37 分钟前
HTML<img>标签
前端·html
嘿siri1 小时前
html全局遮罩,通过websocket来实现实时发布公告
前端·vue.js·websocket·前端框架·vue·html
Lorcian1 小时前
web前端1--基础
前端·python·html5·visual studio code
十三月❀1 小时前
当设置dialog中有el-table时,并设置el-table区域的滚动,看到el-table中多了一条横线
javascript·vue.js·elementui
牧云流1 小时前
Vue3数据响应式原理
javascript·vue.js·ecmascript
不爱学英文的码字机器1 小时前
[JavaScript] 深入理解流程控制结构
开发语言·前端·javascript
violin-wang2 小时前
XML映射文件
xml·java·前端·mybatis