来源:juejin.im/post/5ea63f3ef265da47b177b4b6几种遍历方法中,为了执行最快,它没有任何额外的函数调用堆栈和上下文。但是在实际开发中,我们要结合语义、可读性和程序性能来选择使用哪种方案。下面看看for,foreach,map,for...in,for...of的五个方法现场实战。因为我是第一个出现的遍历语句,大家要叫我爷爷。我可以满足开发人员的大部分需求。//遍历数组letarr=[1,2,3];for(leti=0;ip');for(leti=0;iconsole.log(i))//logs1//logs2//logs3//直接输出数组的元素//遍历对象letprofile={name:"April",nickname:"二十七节",country:"China"};letkeys=Object.keys(profile);keys.forEach(i=>{console.log(i)//对象的键值console.log(profile[i])//对象的key对应的值})map我也发布了ES5版本,我可以新建一个数组,新数组的结果就是原数组中的每个元素都是return调用所提供函数的值。letarr=[1,2,3,4,5];letres=arr.map(i=>i*i);console.log(res)//记录[1,4,9,16,25]for...in枚举在ES5版本中发布。以任何顺序迭代除Symbol之外的对象的可枚举属性。//遍历对象letprofile={name:"April",nickname:"27quarter",country:"China"};for(letiinprofile){letitem=profile[i];console.log(item)//对象的键值console.log(i)//对象的键对应的值//遍历数组letarr=['a','b','c'];for(letiinarr){letitem=arr[i];console.log(item)//数组下标对应的元素console.log(i)//索引,数组下标//遍历字符串letstr="abcd"for(letiinstr){letitem=str[我];console.log(item)//字符串下标对应的元素console.log(i)//索引字符串下标}for...ofIteration我发布的是ES6版本。在可迭代对象(包括Array、Map、Set、String、TypedArray、arguments对象等)上创建迭代循环,调用自定义迭代挂钩,并为每个不同属性的值执行语句。//迭代数组arrayletarr=['a','b','c'];for(letitemofarr){console.log(item)}//logs'a'//logs'b'//logs'c'//迭代字符串letstr="abc";for(letvalueofstr){console.log(value);}//logs'a'//logs'b'//logs'c'//迭代mapletiterable=newMap([["a",1],["b",2],["c",3]]for(letentryofiterable){console.log(entry);}//logs["a",1]//logs["b",2]//logs["c",3]//迭代映射以获得键值for(let[key,value]ofiterable){console.log(key)console.log(value);}//迭代setletiterable=newSet([1,1,2,2,3,3,4]);for(letvalueofiterable){console.log(value);}//logs1//logs2//logs3//logs4//迭代DOM节点){paragraph.classList.add("paragraph");//在名为“article”的节点下的p标签中添加一个名为“paragraph”的类属性。}//迭代参数类数组对象(function(){for(letargumentofarguments){console.log(argument);}})(1,2,3);//日志://1//2//3//迭代类型数组lettypeArr=newUint8Array([0x00,0xff]);for(letvalueoftypeArr){console.log(value);}//logs://0//第一轮后255经过自我介绍和技巧演示,我们了解到for语句是最原始的循环语句.定义一个变量i(number类型,代表数组的下标),按照一定的条件对i进行循环累加。条件通常是循环对象的长度,超过长度就停止循环。因为对象不能确定长度,所以和Object.keys()一起使用。forEachES5提议。自称是for语句的加强版,可以发现写起来比for语句简单很多。但它本质上是数组的一个循环。forEach为每个数组元素执行一次回调函数。这是调用它的数组,因此不会更改原始数组。返回值未定义。地图ES5建议。回调函数按顺序为原始数组中的每个元素调用一次。生成一个新数组而不修改调用它的原始数组本身。返回值是新数组。for...在ES5中提出。遍历对象上的可枚举属性,包括原型对象上的属性,按任意顺序遍历,即顺序不固定。遍历数组时,以数组的下标作为键值。此时,i是一个字符串类型。它是为遍历对象属性而构建的,不建议与数组一起使用。for...ofES6提议。只遍历可迭代对象的数据。作为程序员,仅仅了解它们是不够的,并在实际开发中找出它们各自的优缺点。因地制宜使用,扬长避短。从而提高程序的整体性能才是能力所在。关于跳出循环体,如果循环中满足某些条件则跳出循环体,或者跳过不满足条件的数据继续循环其他数据。是经常遇到的需求。常用的语句有break和continue。简单说说两者的区别,仅作为评测。break语句是跳出当前循环,执行当前循环之后的语句;continue语句是终止当前循环,继续执行下一个循环;注意:forEach和map不支持跳出循环体,其他三个方法支持。原理:看看forEach的实现原理,这个问题就明白了。Array.prototype.forEach(callbackfn[,thisArg]{}这里传入的函数就是回调函数,在回调函数中使用break肯定是不合法的,因为break只能用来跳出循环,而回调函数不是循环体,在回调函数中使用return只是将结果返回给上级函数,也就是for循环,并没有结束for循环,所以return也是无效的。同样是trueformap()。map()链调用map()方法是可以链接的,这意味着它可以很容易地与其他方法结合使用。例如:reduce()、sort()、filter()等.但是其他方法做不到这个.forEach()的返回值是undefined,所以不能链式//元素自己相乘,然后求和.letarr=[1,2,3,4,5];letres1=arr.map(item=>item*item).reduce((total,value)=>total+value);console.log(res1)//logs55undefined"for...in将遍历原型对象的属性Object.prototype.objCustom=function(){};Array.prototype.arrCustom=function(){};vararr=['a','b','c'];arr.foo='hellofor(variinarr){console.log(i);}//logs//0//1//2//foo//arrCustom//objCustom但是在实际开发中,我们并不需要原型对象的属性。在这种情况下我们可以使用hasOwnProperty()方法,它返回一个布尔值,表示该对象在其自身的属性中是否具有指定的属性(即是否具有指定的键)。如下:Object.prototype.objCustom=function(){};Array.prototype.arrCustom=function(){};vararr=['a','b','c'];arr.foo='hellofor(variinarr){if(arr.hasOwnProperty(i)){console.log(i);}}//logs//0//1//2//foo//可以看出数组本身的属性是不能去掉的。这时候推荐使用forEach。对于纯对象的遍历,选择for..in枚举更方便;对于数组遍历,如果不需要知道索引for..of迭代比较合适,因为也可以中断;如果需要知道索引,forEach()比较合适;对于其他字符串、类数组、类型数组的迭代,for..of更占上风,甚至更好。但要注意低版本浏览器的兼容性。对性能感兴趣的读者可以自己找一组数据进行测试,文章会直接给出结果并给出相应的解释。for>for-of>forEach>map>for-infor循环当然是最简单的,因为它没有任何额外的函数调用栈和上下文;for...of可以用它来迭代,只要它的数据结构有Iterator接口成员即可。它直接读取键值。forEach,因为它其实比我们想象的要复杂,它其实就是array.forEach(function(currentValue,index,arr),thisValue)并不是普通for循环的语法糖,有很多参数和上下文需要在执行期间考虑它,这可能会降低性能;map()是最慢的,因为它的返回值是一个全新的等长数组,数组创建和赋值的性能开销非常高。for...in需要穷举对象的所有属性,包括自定义添加的属性,也可以遍历。而for...in的key是String类型,有转换过程,开销比较大。总结在实际开发中,我们需要结合语义、可读性和程序性能来选择使用哪种方案。如果你需要根据一些规则将一个数组映射到另一个数组,你应该使用map。如果需要简单的遍历,使用forEach或者forof。如果需要遍历迭代器,请使用forof。如果您需要过滤掉符合条件的项目,请使用filterr。如果需要先按照规则映射到一个新的数组,然后再根据条件进行过滤,那么就用一个map和一个filter。总之,因地制宜、因时制宜。不要因为过分追求性能而忽视了语义和可读性。在你的统治下,他们五人只能各展所长,谁也不能妄图称霸。近期热点文章推荐:1.1,000+Java面试题及答案(2021最新版)2.别在满屏的if/else中,试试策略模式,真的很好吃!!3.操!Java中xx≠null的新语法是什么?4、SpringBoot2.5发布,深色模式太炸了!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!