while与do-while循环
2025年3月7日大约 6 分钟
while与do-while循环
while和do-while循环是基于条件的循环结构。本文将介绍这两种循环的语法和使用场景,以及它们之间的区别。
while循环
基本语法
while循环的语法如下:
while (条件) {
// 循环体
}
只要指定的条件为真,while循环就会重复执行循环体内的代码。条件在每次循环迭代开始前进行评估。
执行流程
- 检查条件表达式
- 如果为
true
,执行循环体 - 如果为
false
,退出循环
- 如果为
- 执行循环体
- 返回步骤1
示例
// 打印1到5的数字
let i = 1;
while (i <= 5) {
console.log(i);
i++;
}
// 输出: 1, 2, 3, 4, 5
无限循环
如果条件始终为真,将创建无限循环。通常需要在循环体内使用break
语句来退出:
let count = 0;
while (true) {
count++;
console.log(count);
if (count >= 5) {
break; // 当count达到5时退出循环
}
}
// 输出: 1, 2, 3, 4, 5
do-while循环
基本语法
do-while循环的语法如下:
do {
// 循环体
} while (条件);
do-while循环与while循环类似,但有一个重要区别:循环体至少会执行一次,然后才检查条件。
执行流程
- 执行循环体
- 检查条件表达式
- 如果为
true
,返回步骤1 - 如果为
false
,退出循环
- 如果为
示例
// 打印1到5的数字
let i = 1;
do {
console.log(i);
i++;
} while (i <= 5);
// 输出: 1, 2, 3, 4, 5
// 即使条件一开始就为假,循环体也会执行一次
let j = 10;
do {
console.log(j);
j++;
} while (j <= 5);
// 输出: 10
while与do-while的区别
主要区别在于条件检查的时机:
执行顺序:
while
循环先检查条件,再执行循环体do-while
循环先执行循环体,再检查条件
最小执行次数:
while
循环可能一次都不执行(如果条件一开始就为假)do-while
循环至少执行一次,无论条件是否为真
适用场景:
- 当你不确定是否需要执行循环体时,使用
while
- 当你确定至少需要执行一次循环体时,使用
do-while
- 当你不确定是否需要执行循环体时,使用
对比示例
// 条件一开始就为假的情况
// while循环 - 不会执行循环体
let i = 10;
while (i < 5) {
console.log(i);
i++;
}
// 没有输出
// do-while循环 - 会执行一次循环体
let j = 10;
do {
console.log(j);
j++;
} while (j < 5);
// 输出: 10
常见用法和技巧
处理用户输入
do-while循环特别适合处理用户输入验证,因为通常需要至少获取一次输入:
// 模拟用户输入验证
let userInput;
do {
userInput = prompt("请输入一个1到10之间的数字:");
// 转换为数字并验证
userInput = Number(userInput);
} while (isNaN(userInput) || userInput < 1 || userInput > 10);
console.log("有效输入:", userInput);
使用break和continue
与for循环类似,while和do-while循环也可以使用break
和continue
语句:
// 使用break提前退出循环
let i = 1;
while (i <= 10) {
if (i === 5) {
break; // 当i等于5时退出循环
}
console.log(i);
i++;
}
// 输出: 1, 2, 3, 4
// 使用continue跳过当前迭代
let j = 0;
while (j < 10) {
j++;
if (j % 2 === 0) {
continue; // 跳过偶数
}
console.log(j);
}
// 输出: 1, 3, 5, 7, 9
处理未知长度的数据
while循环适合处理长度未知的数据结构,如链表:
// 遍历链表示例
let currentNode = linkedList.head;
while (currentNode !== null) {
console.log(currentNode.value);
currentNode = currentNode.next;
}
实现递归算法的迭代版本
许多递归算法可以使用while循环重写为迭代版本,通常能提高性能:
// 递归版本的阶乘
function factorialRecursive(n) {
if (n <= 1) return 1;
return n * factorialRecursive(n - 1);
}
// 使用while循环的迭代版本
function factorialIterative(n) {
let result = 1;
let i = 2;
while (i <= n) {
result *= i;
i++;
}
return result;
}
console.log(factorialIterative(5)); // 输出: 120
性能考虑
避免无限循环
编写while循环时,确保条件最终会变为false,或者使用break语句退出循环:
// 潜在的无限循环 - 避免这种情况
// while (true) {
// // 如果没有break语句,这将永远运行
// }
// 正确的做法
while (true) {
// 执行某些操作
if (someCondition) {
break; // 提供退出机制
}
}
优化循环条件
尽量简化循环条件,避免在条件中执行复杂计算:
// 不推荐 - 每次迭代都计算数组长度
let i = 0;
while (i < array.length) {
// 循环体
i++;
}
// 推荐 - 只计算一次数组长度
let j = 0;
const len = array.length;
while (j < len) {
// 循环体
j++;
}
实际应用示例
轮询
while循环可用于实现轮询机制:
async function waitForServerResponse() {
let responseReceived = false;
let attempts = 0;
const maxAttempts = 10;
while (!responseReceived && attempts < maxAttempts) {
try {
const response = await checkServerStatus();
if (response.status === 'ready') {
responseReceived = true;
console.log('服务器准备就绪');
} else {
attempts++;
console.log(`等待服务器响应,尝试 ${attempts}/${maxAttempts}`);
// 等待一段时间再次尝试
await new Promise(resolve => setTimeout(resolve, 1000));
}
} catch (error) {
attempts++;
console.error('检查服务器状态时出错:', error);
}
}
if (!responseReceived) {
console.error('达到最大尝试次数,服务器未响应');
}
return responseReceived;
}
游戏循环
while循环常用于实现游戏主循环:
function gameLoop() {
let isGameRunning = true;
let frameCount = 0;
while (isGameRunning) {
// 处理用户输入
processInput();
// 更新游戏状态
update();
// 渲染游戏画面
render();
frameCount++;
// 检查游戏是否结束
if (isGameOver()) {
isGameRunning = false;
console.log(`游戏结束,总帧数: ${frameCount}`);
}
}
}
数据解析
while循环适合处理需要逐步解析的数据:
function parseCSV(csvText) {
const lines = csvText.split('\n');
const result = [];
let i = 0;
// 跳过标题行
if (lines.length > 0) {
i = 1;
}
while (i < lines.length) {
const line = lines[i].trim();
if (line) { // 忽略空行
const values = line.split(',');
result.push(values);
}
i++;
}
return result;
}
与其他循环结构的比较
while vs for
- for循环:当你知道循环的确切次数时更适合使用
- while循环:当循环次数不确定,依赖于某个条件时更适合使用
// 已知迭代次数 - 使用for循环
for (let i = 0; i < 5; i++) {
console.log(i);
}
// 未知迭代次数 - 使用while循环
let randomNumber;
while ((randomNumber = Math.floor(Math.random() * 10)) !== 5) {
console.log(`生成的随机数: ${randomNumber}`);
}
console.log('生成了数字5,循环结束');
while vs for...of
- for...of:用于遍历可迭代对象的所有元素
- while:更通用,可以基于任何条件循环
const numbers = [1, 2, 3, 4, 5];
// 使用for...of遍历所有元素
for (const num of numbers) {
console.log(num);
}
// 使用while有条件地遍历
let i = 0;
while (i < numbers.length && numbers[i] < 4) {
console.log(numbers[i]);
i++;
}
// 输出: 1, 2, 3
总结
while和do-while循环是JavaScript中强大的循环结构,特别适合处理基于条件的重复操作:
- while循环:先检查条件,再执行循环体,适合当你不确定是否需要执行循环体时使用
- do-while循环:先执行循环体,再检查条件,确保循环体至少执行一次,适合需要至少执行一次操作的场景
选择合适的循环结构取决于具体的使用场景:
- 当循环次数已知时,使用
for
循环 - 当循环次数未知,但依赖于某个条件时,使用
while
循环 - 当需要至少执行一次循环体时,使用
do-while
循环
练习
- 使用while循环计算1到100的和
- 编写一个使用do-while循环的猜数字游戏,让用户猜一个1到100之间的随机数
- 使用while循环实现一个简单的倒计时器
- 编写一个函数,使用while循环查找数组中的最大值
- 使用do-while循环实现一个简单的菜单系统,直到用户选择退出选项