来源:https://medium.com/better-programming,作者:Moon,翻译:公众号《前端全栈开发者》JavaScript中一些最流行的功能可能是map和forEach。它们从ECMAScript5(简称es5)开始就存在了。在本文中,我将讨论它们之间的主要区别,并向您展示它们的一些用法示例。阅读之前基本上,在JavaScript中迭代对象取决于对象是否可迭代。数组默认是可迭代的。map和forEach包含在Array.prototype中,因此我们无需担心可迭代性。如果你想了解更多,我建议你看看什么是JavaScript中的可迭代对象!什么是map()和forEach()?map和forEach是数组的辅助方法,可以轻松遍历数组。我们过去常常在没有任何辅助函数的情况下循环遍历如下数组。vararray=['1','2','3'];对于(vari=0;i{console.log(`${i}:${Number(str)}/${origin}`);};arr.map(cb);//0:1/1,2,3//1:2/1,2,3//2:3/1,2,3回调函数可以如下使用。arr.map((str)=>{console.log(Number(str));})map的结果不等于原始数组。constarr=[1];constnew_arr=arr.map(d=>d);arr===new_arr;//false您也可以将对象作为thisArg传递给映射。constobj={name:'Jane'};[1].map(function(){//{name:'Jane'}console.dir(this);},obj);[1].map(()=>{//窗口console.dir(this);},obj);对象obj成为map的thisArg。但是箭头回调函数不能有obj作为它的thisArg。这是因为箭头函数不同于普通函数。forEachforEach是数组的另一个循环函数,但map和forEach的用法不同。map和forEach可以接受两个参数——回调函数和thisArg,它们用作它们的this。constarr=['1','2','3'];//回调函数接受3个参数//数组的当前值作为第一个参数//当前值在数组中的位置作为第二个parameter//原始源数组作为第三个参数constcb=(str,i,origin)=>{console.log(`${i}:${Number(str)}/${origin}`);};arr.forEach(cb);//0:1/1,2,3//1:2/1,2,3//2:3/1,2,3那么有什么区别呢?map返回其原始数组的新数组,但forEach不会。但它们都确保了原始对象的不变性。[1,2,3].map(d=>d+1);//[2,3,4];[1,2,3].forEach(d=>d+1);//不明确的;如果数组内部的值发生变化,forEach不能确保数组的不变性。只有当你不触及里面的任何值时,这个方法才能保证不变性。[{a:1,b:2},{a:10,b:20}].forEach((obj)=>obj.a+=1);//[{a:2,b:2},{a:11,b:21}]//数组改变了!何时使用map()和forEach()?由于它们之间的主要区别在于是否有返回值,因此您会希望使用map来创建一个新数组,而使用forEach只是映射到数组上。这是一个简单的例子。constpeople=[{name:'Josh',whatCanDo:'painting'},{name:'Lay',whatCanDo:'security'},{name:'Ralph',whatCanDo:'cleaning'}];functionmakeWorkers(people){返回人。map((person)=>{const{name,whatCanDo}=person;return我叫{name},我可以做{whatCanDo}});比如在React中,map是一种很常见的制作元素的方法,因为map会在对原数组的数据进行操作后,创建并返回一个新的数组。constmySubjectId=['154','773','245'];函数countSubjects(主题){让cnt=0;subjects.forEach(subject=>{if(mySubjectId.includes(subject.id)){cnt+=1;}});returncnt;}countSubjects([{id:'223',teacher:'Mark'},{id:'154',teacher:'Linda'}]);//1另一方面,当您想在不创建新数组的情况下对数据执行某些操作时,forEach很有用。顺便说一句,可以使用filter重构示例。subjects.filter(subject=>mySubjectId.includes(subject.id)).length;综上所述,我建议大家在新建数组的时候使用map,当你不需要新建数组,但是又想对数据做点什么的时候,就用forEach。速度对比有帖子提到map比forEach快。所以,我很好奇这是不是真的。我找到了这个比较结果。代码看起来很相似,但结果却相反。有些测试说forEach更快,有些说map更快。也许您告诉自己map/forEach比其他的快,您可能是对的。老实说,我不确定。我认为在现代Web开发中,可读性比map和forEach之间的速度重要得多。但有一件事是肯定的——两者都比JavaScript的内置for循环慢。