JavaScript - 循环和迭代

用了这么久的 JS,经常被它的循环方法绕晕,这几种方法的区别,优劣,在此做一个详细总结。

  • for
  • while
  • forEach
  • for…in
  • for…of
  • map

🥈 for / 循环代码块一定的次数

一个for循环会一直重复执行,直到指定的循环条件为fasle。 JavaScript的for循环和Java与C的for循环是很相似的。一个for语句是这个样子的:

1
2
for ([initialExpression]; [condition]; [incrementExpression])
statement

使用示例

1
2
3
for (var i = 0; i < options.length; i++) {
statement
}

break

终止一个 for 循环

continue

跳过余下代码逻辑,直接进入下一个循环。


🥈 While / do…while

一个 while 语句只要指定的条件求值为真(true)就会一直执行它的语句块。一个 while 语句看起来像这样:

1
2
while (condition)
statement

break

终止一个 while 循环

continue

跳过余下代码逻辑,直接进入下一个循环。


🥈 forEach / 数组遍历

forEach 是 ES5 中加入的新的函数,对数组的每个元素执行一次。

1
2
3
array.forEach(callback(currentValue, index, array){
//do something
}, this)

优点是语法简洁;

缺点是不支持使用 break 来中断,也不能 return 进行返回。

配合箭头函数

1
array.forEach(n => console.log(n));

async

forEach 是不支持 async function 的。Polyfill

但可以创建自己的 asyncForEach 方法来方便使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// define
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array)
}
}

// using
const waitFor = (ms) => new Promise(r => setTimeout(r, ms))

const start = async () => {
await asyncForEach([1, 2, 3], async (num) => {
await waitFor(50)
console.log(num)
})
console.log('Done')
}

start()

🥈 for…in / 遍历对象的属性

这个 for…in 语句循环一个指定的变量来循环一个对象所有可枚举的属性。JavaScript 会为每一个不同的属性执行指定的语句。

1
2
3
for (variable in object) {
statements
}

for-in 是为普通对象设计的,可以遍历得到字符串类型的键,因此不适用于数组遍历。

  • 数组的 for-in 循环体除了遍历数组元素外,还会遍历自定义属性
  • 一些情况下,for…in 代码可能按照随机顺序遍历数组元素

🥈 for…of / 全新迭代器循环

for...of 是 ECMA2015 中新加入的,用于可迭代对象上创建循环。

像常见的 Array, Map, Set,String, Collection, 有enumerable属性的对象, generators 等。

缺点

没有 index,要自己实现。

语法

1
2
3
for (variable of object) {
statement
}

示例(与 for…in 的区别)

下面的这个例子展示了 for…of 和 for…in 两种循环语句之间的区别。与 for…in 循环遍历的结果是数组元素的下标不同的是, for…of 遍历的结果是元素的值:

1
2
3
4
5
6
7
8
9
10
let arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) {
console.log(i); // logs "0", "1", "2", "foo"
}

for (let i of arr) {
console.log(i); // logs "3", "5", "7" // 注意这里没有 hello
}

async

for…of 是支持异步使用的,这也是我们常用来进行 async 等待的方法。

1
2
3
4
5
let page = 0;
for (let i of array) {
const products = await fetchProducts(conn, page)
page++;
}

🥈 map

map reduce 是新的高阶函数。它遍历数组中的每一个元素,对期进行一些操作,然后返回一个新的数组。

配合箭头函数

1
array.map(n => console.log(n));

REF::