第5章:语句(Statements)
一、导读
1.1 本章学习目标
第5章介绍JavaScript的控制流语句。本章核心目标:
- 掌握条件语句:if、switch
- 熟练使用各种循环:for、while、for...of、for...in
- 理解异常处理:try-catch-finally
- 掌握标签语句:break和continue与标签配合
1.2 为什么本章如此重要
JavaScript的控制流语句与C/Java类似,但有一些独特之处。特别是for...of和for...in的区别,以及try-catch的错误处理机制,是编写健壮JavaScript代码的基础。
1.3 核心问题引导
for...of和for...in有什么本质区别?
JavaScript的switch语句使用什么比较方式?
try-catch-finally中,如果try和finally都有return,哪个生效?
JavaScript有哪些内置错误类型?
二、核心概念详解
5.1 条件语句
javascript
// if-else
let score = 85;
if (score >= 90) {
console.log("A");
} else if (score >= 80) {
console.log("B");
} else {
console.log("C");
}
// switch(使用===比较)
let day = "Monday";
switch (day) {
case "Monday":
case "Tuesday":
case "Wednesday":
case "Thursday":
case "Friday":
console.log("Weekday");
break;
case "Saturday":
case "Sunday":
console.log("Weekend");
break;
default:
console.log("Invalid");
}
// 三元运算符
let age = 20;
let status = age >= 18 ? "adult" : "minor";5.2 循环语句
javascript
// for循环
for (let i = 0; i < 5; i++) {
console.log(i);
}
// for...of(遍历值,ES6)
let arr = ["a", "b", "c"];
for (let value of arr) {
console.log(value);
}
// for...in(遍历键/索引)
let obj = {a: 1, b: 2, c: 3};
for (let key in obj) {
console.log(`${key}: ${obj[key]}`);
}
// 注意:for...in会遍历原型链上的属性
// 推荐使用Object.keys()
for (let key of Object.keys(obj)) {
console.log(`${key}: ${obj[key]}`);
}
// while
let n = 5;
while (n > 0) {
console.log(n);
n--;
}
// do-while
let m = 0;
do {
console.log(m);
m++;
} while (m < 5);
// break和continue
for (let i = 0; i < 10; i++) {
if (i === 5) break; // 跳出循环
if (i % 2 === 0) continue; // 跳过本次迭代
console.log(i); // 1, 3
}5.3 异常处理
javascript
// try-catch-finally
try {
let result = 10 / 0;
if (result === Infinity) {
throw new Error("Division by zero");
}
} catch (error) {
console.error("Error:", error.message);
} finally {
console.log("Cleanup"); // 总是执行
}
// 自定义错误
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
try {
let age = -1;
if (age < 0) {
throw new ValidationError("Age cannot be negative");
}
} catch (error) {
if (error instanceof ValidationError) {
console.log("Validation:", error.message);
} else {
console.log("Other error:", error.message);
}
}
// 异步错误处理
async function fetchData() {
try {
let response = await fetch("https://api.example.com/data");
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
let data = await response.json();
return data;
} catch (error) {
console.error("Fetch failed:", error);
throw error; // 重新抛出
}
}5.4 标签语句
javascript
// 标签配合break/continue用于多层循环
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
outer: for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] === 5) {
console.log(`Found at [${i}][${j}]`);
break outer; // 跳出外层循环
}
}
}三、实战案例
3.1 数据验证
javascript
function validateUser(user) {
const errors = [];
if (!user.name || typeof user.name !== 'string') {
errors.push("Name is required");
}
if (!user.email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(user.email)) {
errors.push("Valid email is required");
}
if (!user.age || user.age < 0 || user.age > 150) {
errors.push("Valid age is required");
}
if (errors.length > 0) {
throw new ValidationError(errors.join(", "));
}
return true;
}
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
try {
validateUser({name: "", email: "invalid", age: -1});
} catch (error) {
console.log(error.message);
}四、本章小结
第5章讲解了JavaScript的控制流:if/switch条件判断、for/while循环(for...of遍历值,for...in遍历键)、try-catch-finally异常处理、标签语句。
五、思考与练习
思考题
for...of和for...in有什么区别?什么时候用哪个?
switch使用什么比较方式?和if-else有什么不同?
finally块中的代码在什么情况下不会执行?
如何创建自定义错误类型?
编程练习
使用for...of遍历一个Map对象。
实现一个带重试的异步请求函数。
编写一个函数,验证用户输入并抛出适当的错误。