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 | ❌ | ❌ | |
forEach | ❌ | ✔ | ❌ | undefined | ✔ | |
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个只能是各自发挥长处,谁都别想称霸。