js中forEach, fof...of fon...in, map, for五种循环的区别

文章描述

js中forEach, fof...of fon...in, map, for五种循环的区别?该怎么使用?何时使用某一种更适合呢?

面试和平时开发过程遇到这样的问题,js中的这五种循环怎该怎么使用呢???

  • for
  • for..in
  • forEach
  • map
  • for...of


几种遍历方法中for执行最快,它没有任何额外的函数调用栈和上下文。但在实际开发中我们要结合语义话、可读性和程序性能,去选择究竟使用哪种方案。

break / continue遍历数组遍历对象返回值性能下标
for 最好
for...in
for...of默认不支持,可通过配置Symbol.iterator
forEachundefined
map


for语法

for (let index = 0; index < array.length; index++) {
   const element = array[index];
   ...
}

for...in语法

我是ES5版本发布的。以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

for (const key in object) {
   const item = object[key];
}

for...of语法

我是ES6版本发布的。在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。

for (const item of array) {
  ...
}

forEach语法

我是ES5版本发布的。按升序为数组中含有效值的每一项执行一次 callback 函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。我是 for 循环的加强版

array.forEach((item, index, originArray) => {
   ...
})

map语法

  • 返回一个新数组; 可以用过return返回值,没有return时数组的每一项是undefined
  • 不会修改原数组, 如果是遍历时,修改了item,并且item是引用类型除外
array.map((value, index, originArray) => {
   ...
})


对象添加Symbol.iterator

let obj = { a: 2, b: 5, c: 8 };

obj[Symbol.iterator] = function() {
   return {
     next:function(){
     let objArr = Reflect.ownKeys(obj)
     if (this.index < objArr.length-1) {
       let key = objArr[this.index];
       this.index++;
       return { value: obj[key] };
   } else {
       return { done: true };
   }
  },
   index:0
 }
}

for (let item of obj) {
 console.log(item);
}


性能

  • for 循环当然是最快的的,因为它没有任何额外的函数调用栈和上下文;
  • for...of只要具有Iterator接口的数据结构,都可以使用它迭代成员。它直接读取的是键值。
  • forEach,因为它其实比我们想象得要复杂一些,它实际上是array.forEach(function(currentValue, index, arr), thisValue)它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能;
  • map() 最慢,因为它的返回值是一个等长的全新的数组,数组创建和赋值产生的性能开销很大。
  • for...in需要穷举对象的所有属性,包括自定义的添加的属性也能遍历到。且for...in的key是String类型,有转换过程,开销比较大。



总结:

在实际开发中我们要结合语义话、可读性和程序性能,去选择究竟使用哪种方案。

如果你需要循环大量数据,选择for是最好的选择

如果你需要将数组按照某种规则映射为另一个数组,就应该用 map。

如果你需要进行简单的遍历,用 forEach 或者 for of。

如果你需要对迭代器进行遍历,用 for of。

如果你需要过滤出符合条件的项,用 filterr。

如果你需要先按照规则映射为新数组,再根据条件过滤,那就用一个 map 加一个 filter。

总之,因地制宜,因时而变。千万不要因为过分追求性能,而忽略了语义和可读性。在您的统治之下,他们5个只能是各自发挥长处,谁都别想称霸。

评论(共0条)