六维教程

JavaScript for 循环

上一篇的 while 循环把初始值、条件、更新三部分拆开写,代码能正常运行,但三部分分散各处,读起来要来回找。for 循环把这三部分集中到一行,是实际开发里用得最多的循环。这篇就讲 for 循环。

for 的三段式结构

for 括号里用两个分号隔开三段,依次是初始化、条件、更新。

for (初始化; 条件; 更新) {
  // 循环体
}

执行顺序是初始化只跑一次,然后判断条件,为 true 执行循环体,执行完跑更新语句,再判断条件,如此反复。用 for 重写 1 加到 100

let sum = 0;

for (let i = 1; i <= 100; i++) {
  sum = sum + i;
}

console.log(sum); // 输出 5050

对比上一篇的 while 写法,三要素都集中在一行里,条件更新不容易漏写。按固定次数循环用 for 更合适,while 适合条件本身比较复杂的情况。

遍历数组

for 最常见的用途是按索引遍历数组。数组是装多个值的数据结构,用方括号创建,按下标访问元素,arr[0] 是第一个元素,arr.length 是元素个数。

const fruits = ['苹果', '香蕉', '橘子'];

for (let i = 0; i < fruits.length; i++) {
  console.log(fruits[i]);
}

输出结果

苹果
香蕉
橘子

i 从 0 到 length - 1,正好覆盖数组每个元素。这种写法在后面讲数组的文章里会大量使用。如果只想按顺序取出每个值,不想管下标,ES6 还提供了 for…of 写法,一句带过,后面数组教程再细讲。

for (const fruit of fruits) {
  console.log(fruit);
}

continue 跳过本次迭代

break 是结束整个循环,continue 是跳过本次迭代,直接进入下一次。比如只输出 1 到 10 里的偶数

for (let i = 1; i <= 10; i++) {
  if (i % 2 !== 0) {
    continue; // 奇数跳过,不执行下面的输出
  }
  console.log(i);
}

输出结果

2
4
6
8
10

i 为奇数时执行 continue,本次循环体剩下的代码不执行,直接进入 i++ 和下一次判断。

循环变量用 let 的好处

for 的初始化语句里用 let 声明循环变量,这个变量只在 for 的花括号里有效,外面访问不到。

for (let i = 0; i < 3; i++) {
  console.log(i);
}

console.log(i); // 报错,i 在块外不存在

更重要的特性是每次迭代都会创建独立的变量绑定。把函数存到数组里,用 let 时每个函数记住的是自己那一轮的 i 值。

const fns = [];

for (let i = 0; i < 3; i++) {
  fns.push(function () {
    console.log(i);
  });
}

fns[0](); // 输出 0
fns[1](); // 输出 1
fns[2](); // 输出 2

如果换成 var(旧语法),三个函数会输出同一个值 3。因为 var 没有块级作用域,所有迭代共享同一个变量。这也是本教程坚持用 let 的重要原因,后面讲闭包时会再次遇到这个特性。

嵌套循环

循环体里还可以再写循环,叫嵌套循环。外层每执行一次,内层要完整跑完一轮。经典例子是九九乘法表

for (let i = 1; i <= 9; i++) {
  let line = '';
  for (let j = 1; j <= i; j++) {
    line = line + j + '*' + i + '=' + i * j + '  ';
  }
  console.log(line);
}

每行由内层循环拼接而成,i 固定时 j 从 1 跑到 i。嵌套循环在遍历二维结构时很常用,先理解外层走一圈、内层走完一轮的顺序。

小结

  • for 的三段式结构把初始化、条件、更新集中在一行,执行顺序是初始化、判断、循环体、更新、再判断。
  • 按索引遍历数组是最常见用法,i 从 0 到 length - 1,用 arr[i] 访问元素。
  • continue 跳过本次迭代继续下一次,break 结束整个循环。
  • 循环变量用 let 时拥有块级作用域,每次迭代都是独立绑定,这是本教程不用 var 的原因之一。
  • 循环可以嵌套,外层每执行一次内层完整执行一轮。
上一篇
JavaScript while 与 do-while 循环
下一篇
JavaScript 函数的定义与调用