For 循环
不必多说,最基础的循环
For of 与 for in循环
for of 循环的值必须是一个iterable, iterable是一个能够产生迭代器来可以使循环进行的对象。JS里默认为(或提供)iterable的标准内建值有Arrays、Strings、Generators、Collections/TypedArrays。
我们可以通过以下代码来对比一下for of 与 for in的区别:
let testData = ['a', 'b', 'c', 'd']
for (let index in testData) {
console.log(index)
}
// 0、1、2、3
for (let value of testData) {
console.log(value)
}
// a、b、c、d
可以看到,for in 在数组的键/索引上进行循环, 而for of在数组的value值上进行循环。故for in多用于根据对象key值循环而for of多用于数组/字符串循环。
Foreach、map与filter
我们先看一下这三种循环各自的使用方式:
Array.forEach((item, index ,arr) => {
// todo...
})
Array.map((item, index ,arr) => {
// todo...
})
Array.filter((item, index ,arr) => {
// todo...
})
这三种循环都有三个参数,分别是每次循环的值,值的索引以及循环的原数组。
map()
map()方法会返回一个由原数组中的每个元素调用一个指定方法后的结果组成的新数组。
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。
let testData = [1, 2, 3, 4, 5, 6]
const res = testData.map((item, index, arr) => {
if (item > 3) {
return item
}
})
// [ undefined, undefined, undefined, 4, 5, 6 ]
foreach()
foreach同样是遍历,但是没有返回值,仅仅是遍历数组中的每一项,不对原来数组进行修改
不能使用break语句中断循环,也不能使用return语句返回到外层函数,但是可以自己通过数组索引来修改原来的数组:
let testData = ['a', 'b', 'c', 'd']
testData.forEach((item, index ,arr) => {
item = item + '1'
})
// ['a', 'b', 'c', 'd']
testData.forEach((item, index ,arr) => {
arr[index] = item + '1'
})
// ['a1', 'b1', 'c1', 'd1']
filter()
filter()方法是对原数组进行过滤筛选,产生一个新的数组对象。
filter()不会对空数组进行检测(如果对空数组进行筛选,返回值位undefined)。
filter()不会改变原始数组,返回的数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。
let testData = [1, 2, 3, 4, 5, 6]
const res = testData.filter((item, index, arr) => {
if (item > 3) {
return item
}
})
// [ 4, 5, 6 ]
通过filter与map的例子对比,可以看出filter与map的少许区别,map更多的是对原数组的一个映射,适合对所有数组成员进行一定的处理,如果要对数组成员进行筛选遍历,未通过的则会默认返回undefined,而filter则更多用于对原数组的筛选遍历。
性能
如果只谈性能,显然是 for > forEach > map
为什么 for 的性能比较好?因为它没有任何额外的函数调用栈和上下文;
forEach 其次,因为它其实比我们想象得要复杂一些,它的函数签名实际上是
array.forEach(function(currentValue, index, arr), thisValue)
它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能;
map 最慢,因为它的返回值是一个等长的全新的数组,数组创建和赋值产生的性能开销很大。
总结
如果你需要将数组按照某种规则映射为另一个数组,就应该用 map。
如果你需要进行简单的遍历,用 forEach 或者 for of。
如果你需要对迭代器进行遍历,用 for of.如果你需要过滤出符合条件的项,用 filter。
如果你需要先按照规则映射为新数组,再根据条件过滤,那就用一个 map 加一个 filter。
不要担心这样会慢,你那点数据量浏览器根本不 care。如果你真的需要考虑性能,或者有 break 的需求,就用 for 吧。