流程控制语句
本章将详细介绍ECMAScript中的流程控制语句,包括条件语句、循环语句和跳转语句,帮助您控制程序的执行流程。
7.1 流程控制概述
流程控制语句用于控制程序的执行顺序。默认情况下,程序按顺序执行语句,但通过流程控制语句可以改变执行顺序,实现条件执行、循环执行和跳转执行。
7.2 条件语句
条件语句根据条件的真假来决定是否执行特定代码块。
if语句
// 基本if语句
let age = 18;
if (age >= 18) {
console.log("您已成年");
}
// if-else语句
if (age >= 18) {
console.log("您已成年");
} else {
console.log("您未成年");
}
// if-else if-else语句
if (age < 13) {
console.log("儿童");
} else if (age < 20) {
console.log("青少年");
} else if (age < 60) {
console.log("成年人");
} else {
console.log("老年人");
}
嵌套if语句
let score = 85;
let subject = "数学";
if (subject === "数学") {
if (score >= 90) {
console.log("数学优秀");
} else if (score >= 80) {
console.log("数学良好");
} else {
console.log("数学需要努力");
}
}
条件(三元)运算符
// 简单条件赋值
let status = age >= 18 ? "成年人" : "未成年人";
// 复杂条件表达式
let message = score >= 90 ? "优秀" :
score >= 80 ? "良好" :
score >= 60 ? "及格" : "不及格";
7.3 switch语句
switch语句用于基于不同条件执行不同代码块。
基本switch语句
let day = 3;
let dayName;
switch (day) {
case 1:
dayName = "星期一";
break;
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三";
break;
case 4:
dayName = "星期四";
break;
case 5:
dayName = "星期五";
break;
case 6:
dayName = "星期六";
break;
case 7:
dayName = "星期日";
break;
default:
dayName = "无效的日期";
}
console.log(dayName); // "星期三"
fallthrough行为
// 利用fallthrough特性
let grade = 'B';
let comment;
switch (grade) {
case 'A':
comment = "优秀";
// 注意:没有break语句
case 'B':
comment = "良好";
// 注意:没有break语句
case 'C':
comment = "一般";
break;
default:
comment = "需要改进";
}
console.log(comment); // "一般" (因为fallthrough)
7.4 循环语句
循环语句用于重复执行代码块。
for循环
// 基本for循环
for (let i = 0; i < 5; i++) {
console.log(`第${i + 1}次循环`);
}
// 倒序循环
for (let i = 10; i >= 0; i--) {
console.log(i);
}
// 循环数组
let fruits = ["苹果", "香蕉", "橙子"];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
for-in循环
// 遍历对象属性
let person = {
name: "张三",
age: 25,
city: "北京"
};
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
// 遍历数组索引
let colors = ["红", "绿", "蓝"];
for (let index in colors) {
console.log(`${index}: ${colors[index]}`);
}
for-of循环 (ES6)
// 遍历数组元素
let fruits = ["苹果", "香蕉", "橙子"];
for (let fruit of fruits) {
console.log(fruit);
}
// 遍历字符串
let str = "Hello";
for (let char of str) {
console.log(char);
}
// 遍历Set
let uniqueNumbers = new Set([1, 2, 3, 4, 5]);
for (let num of uniqueNumbers) {
console.log(num);
}
// 遍历Map
let userRoles = new Map([
["张三", "管理员"],
["李四", "用户"],
["王五", "访客"]
]);
for (let [user, role] of userRoles) {
console.log(`${user}: ${role}`);
}
while循环
// 基本while循环
let count = 0;
while (count < 5) {
console.log(`计数: ${count}`);
count++;
}
// 使用while处理未知次数的循环
let userInput;
while (userInput !== "退出") {
userInput = prompt("输入'退出'结束程序");
console.log(`您输入了: ${userInput}`);
}
do-while循环
// do-while循环至少执行一次
let password;
do {
password = prompt("请输入密码");
} while (password !== "123456");
console.log("密码正确,登录成功");
7.5 跳转语句
跳转语句用于改变程序的正常执行流程。
break语句
// 在循环中使用break
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // 当i等于5时跳出循环
}
console.log(i); // 输出0, 1, 2, 3, 4
}
// 在switch中使用break
let command = "保存";
switch (command) {
case "保存":
console.log("正在保存文件...");
break;
case "打开":
console.log("正在打开文件...");
break;
case "关闭":
console.log("正在关闭文件...");
break;
default:
console.log("未知命令");
}
continue语句
// 跳过循环中的某些迭代
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) {
continue; // 跳过偶数
}
console.log(i); // 输出1, 3, 5, 7, 9
}
// 在while循环中使用continue
let num = 0;
while (num < 10) {
num++;
if (num % 3 === 0) {
continue; // 跳过3的倍数
}
console.log(num);
}
标签语句
// 使用标签跳出嵌套循环
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) {
break outer; // 跳出外层循环
}
console.log(`i=${i}, j=${j}`);
}
}
// 使用标签继续外层循环
outer2: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) {
continue outer2; // 跳过外层循环的当前迭代
}
console.log(`i=${i}, j=${j}`);
}
}
7.6 异常处理语句
异常处理语句用于处理程序运行时可能出现的错误。
try-catch语句
// 基本异常处理
try {
let result = riskyOperation();
console.log(result);
} catch (error) {
console.log("发生错误:", error.message);
}
// 处理特定类型的错误
try {
JSON.parse(invalidJsonString);
} catch (error) {
if (error instanceof SyntaxError) {
console.log("JSON格式错误");
} else {
console.log("其他错误:", error.message);
}
}
finally语句
// finally块总是执行
try {
console.log("尝试执行");
throw new Error("出错了");
} catch (error) {
console.log("捕获错误:", error.message);
} finally {
console.log("清理资源");
}
// 无论是否发生异常,finally都会执行
function divide(a, b) {
try {
if (b === 0) {
throw new Error("除数不能为零");
}
return a / b;
} catch (error) {
console.log("计算错误:", error.message);
return null;
} finally {
console.log("计算完成");
}
}
7.7 流程控制的最佳实践
避免深层嵌套
// 不推荐:深层嵌套
function processUser(user) {
if (user) {
if (user.isActive) {
if (user.age >= 18) {
if (user.hasPermission) {
// 处理用户
}
}
}
}
}
// 推荐:早期返回
function processUser(user) {
if (!user) return;
if (!user.isActive) return;
if (user.age < 18) return;
if (!user.hasPermission) return;
// 处理用户
}
合理使用标签
// 在复杂的嵌套循环中使用标签提高可读性
processMatrix: for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] === target) {
console.log(`找到目标在位置(${i}, ${j})`);
break processMatrix;
}
}
}
提示:合理使用流程控制语句可以让程序逻辑更清晰,但要避免过度复杂的嵌套结构。适当的函数拆分和早期返回可以让代码更易读和维护。