循环

2018-02-24大约6分钟

循环是指当条件为true时,反复执行某个代码块。JavaScript使用两个语句来达到这个目的:for语句和while语句。

for语句

for语句可以将某段代码重复执行指定次数。先来体验一下:

for (let loopCounter = 1; loopCounter <= 5; loopCounter++) {
    console.log(loopCounter);
}

上面的例子,语法如下图所示

图片

for语句主要有三部分:

  1. 初始化部分,在循环的执行过程中,这个部分只执行一次。在上面的例子中,我们定义了一个变量loopCounter;
  2. 测试条件部分,只要测试条件为true,就会继续执行循环体中的代码;
  3. 更新循环变量部分,这部分用来控制循环的次数,通常可以递增或递减。

再来看更多的例子:

for (var i = 0; i < 5; i++) {
    console.log(i);
}

console.log("----------分隔符----------");
for (var i = 5; i > 0; i--) {
    console.log(i);
}

console.log("----------分隔符----------");
for (var i = 5; i > 0; i = i - 2) {
    console.log(i);
}

for...in

for...in语句可以遍历一个对象上的可枚举的属性。

const user = { name: "Tom", age: 16, gender: "male" };

for (let prop in user) {
    console.log(`${prop}: ${user[prop]}`);
}
可枚举属性
可枚举属性指的是对象上内部标记Enumerable为true的属性,涉及对象内部实现。简单理解的话,给对象初始化的属性(包含数组里的值)、赋值时创建的属性都是可枚举的。

由于数组里的元素也是可以枚举的,因此也可以用for...in语句来遍历。

const people = ["Tom", "Mary", "Tim"];

for (let person in people) {
    console.log(person);
}
一般情况下,不要在遍历的时候,增添或删除对象的属性,可能会影响遍历的结果

虽然for...in可以用来遍历数组,但是也会出现一些意想不到的副作用:

  • for...in不能保证按数组中元素的顺序遍历
  • 因为JS时动态语言,有时候你期望遍历的数组可能并不是个数组,而是个普通对象,这时候for...in也是可以遍历,不会错,但这很可能不是你希望的

因此,不建议用for...in来遍历数组,而是用数组本身的forEach函数来遍历:

const people = ["Tom", "Mary", "Tim"];
people.forEach(function (person) {
  console.log(person);
});

While语句

for循环用于迭代特定的次数,而while循环可测试一个条件,在条件为true的时候,继续迭代。while循环在不知道循环次数的时候比较有效。

let num = 1;
while (true) {
    if ((num % 2 === 0) & (num % 3 === 0)) {
        console.log(num);
        break;
    }

    num++;
}

上面例子的代码是为了寻找2和3的最小公倍数。while的测试条件始终为true,找到就用break语句退出循环。

使用while的时候,要注意无限循环——永远不会结束的循环,要仔细测试代码保证不会出现,否则会导致CPU的一个核心占用100%且程序无响应。