日常生活中经常需要执行一些重复的操作。

while 循环则提供了一种循环执行代码的方式,语法如下:

while (condition) {
    code
}

conditiontrue 时,会一直执行 code 中的内容。

$$edit$$
$$jsdemo$$
let hour = 2
while (hour < 6) {
    alert(`才${hour}点,打工!`)
    hour++
}
alert(`${hour}点了,下班!`)

死循环

格外注意的是, condition 判断条件需要在某一时刻为 false 或者有 break 结束循环。否则会一直在循环内无法结束,被称为死循环。后续的代码也会无法执行,严重的情况下会造成页面没有响应(卡死)。

$$edit$$
$$jsdemo$$
let hour = 2
while (hour < 6) {
    alert(`才${hour}点,打工!`) // 永远无法结束的打工生涯
}
alert(`${hour}点了,下班!`)

$$tip

如果运行代码导致页面卡死可以选择直接关闭页面。

$$

break 关键字

break 出现在循环中时会起到结束当前循环的作用,因此可以用 break 改写以上的代码。

$$edit$$
$$jsdemo$$
let hour = 2
while (true) {
    alert(`才${hour}点,打工!`)
    hour++

    if (hour >= 6) {
        break
    }
}
alert(`${hour}点了,下班!`)

结束标签处的循环

break <labelName> 可以让代码结束标签处的循环,语法如下:

labelName: while (condition) {
    break labelName
}

这是因为 break 只能结束当前循环,如果存在多层循环有时会出现结束上层循环的需求。

$$edit$$
$$jsdemo$$
let today = 1
let hour = 2
while (today <= 5) {
    while (hour < 6) {
        if (today == 2 && hour == 3) {
            console.log("腿断了,休假。")
            break
        }

        console.log(`今天周${today},才${hour}点,打工!`)
        hour++
    }
    hour = 2
    today++
}

比如以上的代码中,腿断了应该休假一整周,而不止一天。

$$tip

打开开发者控制台查看 console.log 输出的值。

$$

修改成以下代码,来结束标记处的循环。

$$edit$$
$$jsdemo$$
let today = 1
let hour = 2
week: while (today <= 5) {
    while (hour < 6) {
        if (today == 2 && hour == 3) {
            console.log("腿断了,休假。")
            break week
        }

        console.log(`今天周${today},才${hour}点,打工!`)
        hour++
    }
    hour = 2
    today++
}

continue 关键字

continue 关键字可以跳过当前循环直接进入下一次循环。

$$edit$$
$$jsdemo$$
let hour = 2
while (hour < 6) {
    if (hour == 3) {
        alert("3点了,饮茶先啊。")
        hour++
        continue
    }

    alert(`才${hour}点,打工!`)
    hour++
}
alert(`${hour}点了,下班!`)

do...while 循环

do...while 循环与 while 循环类似,唯一的不同点在于:

  • while 每轮代码执行前都会进行条件判断,再决定是否执行代码。
  • do...while 先执行一次代码,之后与 while 一致。 这保证了 do...while 至少会执行一次。
do {
    // code
} while (condition)
$$jsdemo$$
$$edit$$
do {
    alert("至少被执行一次")
} while (false)

$$tip

do ... while 的使用场景较少,可以不用过多理解。

$$


练习

  1. 这个月有 30 天,2 号是周四。周日分别都是多少号,将它们找(alert)出来。 $$demo <button onclick="find()">找周日</button> <script> function find() { // 第一个周日 let day = 5

while (day <= 30) { alert(${day} 号是周日)

day += 7

} } </script> $$ $$answer

$$jsdemo$$
$$edit$$
// 第一个周日
let day = 5

while (day <= 30) {
    alert(`${day} 号是周日`)

    day += 7
}

$$

  1. 用户输入一个正整数,判断其是否是质数 。 $$tip 质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。 $$

$$demo <button onclick="judge()">判断质数</button> <script> function judge() { let n = Number(prompt("请输入一个正整数:"))

    // 先假设是质数
    let isPrime = true

    // 计数器
    let i = 2

    while (i < n) {
        if (n % i == 0) {
            // 求余为 0 表示能被整除
            // 肯定不是质数
            isPrime = false
            break
        }

        i++
    }

    if (n === 1) {
        isPrime = false
    }

    if (isPrime) {
        alert(`${n} 是质数。`)
    } else {
        alert(`${n} 不是质数。`)
    }
}

</script> $$

$$answer

$$jsdemo$$
$$edit$$
let n = Number(prompt("请输入一个正整数:"))

// 先假设是质数
let isPrime = true

// 计数器
let i = 2

while (i < n) {
    if (n % i == 0) {
        // 求余为 0 表示能被整除
        // 肯定不是质数
        isPrime = false
        break
    }

    i++
}

if (n === 1) {
    isPrime = false
}

if (isPrime) {
    alert(`${n} 是质数。`)
} else {
    alert(`${n} 不是质数。`)
}

$$

  1. 设计一个程序,打印(console.log)出 100 以内的所有质数

$$demo <button onclick="find()">找质数</button> <span>提示:按 F12 打开控制台查看输出</span> <script> function find() { let n = 2 while (n < 100) { let n2 = 2 let isPrime = true

        while (n2 < n) {
            if (n % n2 == 0) {
                // 求余为 0 表示能被整除
                // 肯定不是质数
                isPrime = false
                break
            }

            n2++
        }

        if (isPrime) {
            console.log(`${n} 是质数。`)
        }
        n++
    }
}

</script> $$

$$answer

$$jsdemo$$
$$edit$$
let n = 2
while (n < 100) {
    let n2 = 2
    let isPrime = true

    while (n2 < n) {
        if (n % n2 == 0) {
            // 求余为 0 表示能被整除
            // 肯定不是质数
            isPrime = false
            break
        }

        n2++
    }

    if (isPrime) {
        console.log(`${n} 是质数。`)
    }
    n++
}
$$

4. 存在一个正整数 a(用户输入),求出它的正[约数](https://baike.baidu.com/item/%E7%BA%A6%E6%95%B0/8417882?fr=aladdin)。
$$tip
约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。

在自然数(0和正整数)的范围内,

- 4的正约数有:1、2、4。
- 6的正约数有:1、2、3、6。
- 10的正约数有:1、2、5、10。
- 12的正约数有:1、2、3、4、6、12。
- 15的正约数有:1、3、5、15。
- 18的正约数有:1、2、3、6、9、18。
- 20的正约数有:1、2、4、5、10、20。


注意:一个数的约数必然包括1及其本身。
$$

$$demo
<button onclick="find()">求约数</button>
<span>提示:按 F12 打开控制台查看输出</span>
<script>
    function find() {
        let a = Number(prompt("请输入一个正整数 a:"))

        console.log(`${a} 的约数有:`)
        let n = 1
        while (n <= a) {
            if (a % n === 0) {
                console.log(n)
            }

            n++
        }
    }
</script>
$$


$$answer
```javascript
$$jsdemo$$
$$edit$$
let a = Number(prompt("请输入一个正整数 a:"))

console.log(`${a} 的约数有:`)
let n = 1
while (n <= a) {
    if (a % n === 0) {
        console.log(n)
    }

    n++
}
$$


5. 存在两个正整数 a、b(用户输入),求出它们的[最大公约数](https://zh.wikipedia.org/wiki/%E6%9C%80%E5%A4%A7%E5%85%AC%E5%9B%A0%E6%95%B8)。
$$tip
“最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。a,b的最大公约数记为(a,b),同样的,a,b,c的最大公约数记为(a,b,c),多个整数的最大公约数也有同样的记号。

例如
- (10, 12) = 2
- (12, 16) = 4
- (8, 16) = 8
- (9, 15) = 3
- (24, 32) = 8
$$

$$demo
<button onclick="find()">求最大公约数</button>
<script>
    function find() {
        let a = Number(prompt("请输入一个正整数 a:"))
        let b = Number(prompt("请输入一个正整数 b:"))

        // a、b 中的较小值
        let min = a < b ? a : b

        // 最大公约数
        let greatestDivisor = 1

        let n = 1
        while (n <= min) {
            if (a % n === 0 && b % n === 0) {
                // 此时 b 是 a、b 的公约数
                greatestDivisor = n
            }
            n++
        }

        alert(`(${a},${b}) = ${greatestDivisor}`)
    }
</script>

$$

$$answer
```javascript
$$jsdemo$$
$$edit$$
let a = Number(prompt("请输入一个正整数 a:"))
let b = Number(prompt("请输入一个正整数 b:"))

// a、b 中的较小值
let min = a < b ? a : b

// 最大公约数
let greatestDivisor = 1

let n = 1
while (n <= min) {
    if (a % n === 0 && b % n === 0) {
        // 此时 b 是 a、b 的公约数
        greatestDivisor = n
    }
    n++
}

alert(`(${a},${b}) = ${greatestDivisor}`)
$$