JavaScript 控制流
控制流决定了代码执行的顺序。本章将介绍条件语句和循环结构。
条件语句
if 语句
let age = 18;
if (age >= 18) {
console.log("已成年");
}
if...else 语句
let score = 75;
if (score >= 60) {
console.log("及格");
} else {
console.log("不及格");
}
if...else if...else 语句
let grade = 85;
if (grade >= 90) {
console.log("优秀");
} else if (grade >= 80) {
console.log("良好");
} else if (grade >= 60) {
console.log("及格");
} else {
console.log("不及格");
}
嵌套 if 语句
let age = 25;
let hasLicense = true;
if (age >= 18) {
if (hasLicense) {
console.log("可以开车");
} else {
console.log("需要考驾照");
}
} else {
console.log("年龄不够");
}
逻辑运算符组合条件
let age = 25;
let income = 50000;
if (age >= 18 && income > 30000) {
console.log("符合贷款条件");
} else {
console.log("不符合贷款条件");
}
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); // "星期三"
多个 case 匹配相同结果
let grade = 3;
let result;
switch (grade) {
case 1:
case 2:
case 3:
result = "初级";
break;
case 4:
case 5:
case 6:
result = "中级";
break;
default:
result = "高级";
}
console.log(result); // "初级"
switch 使用严格比较
let value = "1";
let num = 1;
switch (value) {
case 1:
console.log("数字 1"); // 不执行
break;
case "1":
console.log("字符串 '1'"); // 执行
break;
}
三元运算符
适合简单的二选一情况:
let age = 20;
let status = age >= 18 ? "成年人" : "未成年人";
console.log(status); // "成年人"
// 替代简单的 if...else
let isEven = 10 % 2 === 0 ? "偶数" : "奇数";
循环
for 循环
// 基本 for 循环
for (let i = 0; i < 5; i++) {
console.log(i); // 0, 1, 2, 3, 4
}
// 遍历数组
let fruits = ["苹果", "香蕉", "橙子"];
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// 遍历字符串
let str = "Hello";
for (let i = 0; i < str.length; i++) {
console.log(str[i]);
}
for...in 循环
遍历对象的可枚举属性:
// 遍历对象属性
let person = {
name: "张三",
age: 20,
city: "北京"
};
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
// 输出:
// name: 张三
// age: 20
// city: 北京
// 遍历数组索引(不推荐,数组也可用)
let arr = [10, 20, 30];
for (let index in arr) {
console.log(index); // "0", "1", "2"
}
for...of 循环
遍历可迭代对象(数组、字符串、Map、Set 等):
// 遍历数组
let fruits = ["苹果", "香蕉", "橙子"];
for (let fruit of fruits) {
console.log(fruit);
}
// 遍历字符串
let str = "Hello";
for (let char of str) {
console.log(char);
}
// 使用索引
for (let [index, fruit] of fruits.entries()) {
console.log(`${index}: ${fruit}`);
}
while 循环
先判断后执行:
let count = 0;
while (count < 5) {
console.log(count);
count++;
}
// 输出:0, 1, 2, 3, 4
do...while 循环
先执行后判断(至少执行一次):
let count = 0;
do {
console.log(count);
count++;
} while (count < 0);
// 输出:0(即使条件不满足也会执行一次)
循环控制
break 语句
立即退出循环:
// 找到第一个偶数
for (let i = 1; i <= 10; i++) {
if (i % 2 === 0) {
console.log(`第一个偶数是:${i}`);
break;
}
}
// 输出:第一个偶数是:2
continue 语句
跳过当前迭代,继续下一次循环:
// 打印 1-10 的奇数
for (let i = 1; i <= 10; i++) {
if (i % 2 === 0) {
continue; // 跳过偶数
}
console.log(i); // 1, 3, 5, 7, 9
}
嵌套循环
// 打印九九乘法表
for (let i = 1; i <= 9; i++) {
let row = "";
for (let j = 1; j <= i; j++) {
row += `${j}×${i}=${i*j}\t`;
}
console.log(row);
}
label 语句
为循环添加标签,用于控制多层嵌套循环:
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
console.log(`i=${i}, j=${j}`);
if (j === 1) {
break outer; // 直接跳出外层循环
}
}
}
// 只输出:
// i=0, j=0
// i=0, j=1
高级循环技巧
数组的 forEach 方法
let numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(number, index) {
console.log(`索引 ${index}: ${number}`);
});
// 使用箭头函数
numbers.forEach((number, index) => {
console.log(`索引 ${index}: ${number}`);
});
数组的 map 方法
创建新数组:
let numbers = [1, 2, 3, 4, 5];
let squared = numbers.map(num => num ** 2);
console.log(squared); // [1, 4, 9, 16, 25]
数组的 filter 方法
过滤数组元素:
let numbers = [1, 2, 3, 4, 5, 6];
let evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4, 6]
数组的 reduce 方法
汇总数组元素:
let numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15
// 计算平均值
let avg = numbers.reduce((acc, num, idx, arr) => {
acc += num;
if (idx === arr.length - 1) {
return acc / arr.length;
}
return acc;
}, 0);
console.log(avg); // 3
循环的实际应用
计算阶乘
function factorial(n) {
if (n < 0) return -1;
if (n === 0 || n === 1) return 1;
let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}
console.log(factorial(5)); // 120
斐波那契数列
function fibonacci(n) {
if (n <= 0) return 0;
if (n === 1) return 1;
let a = 0, b = 1;
for (let i = 2; i <= n; i++) {
let temp = a + b;
a = b;
b = temp;
}
return b;
}
// 输出前 10 个斐波那契数
for (let i = 0; i < 10; i++) {
console.log(fibonacci(i));
}
// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
判断质数
function isPrime(n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 === 0 || n % 3 === 0) return false;
for (let i = 5; i * i <= n; i += 6) {
if (n % i === 0 || n % (i + 2) === 0) {
return false;
}
}
return true;
}
// 打印 1-100 的质数
for (let i = 1; i <= 100; i++) {
if (isPrime(i)) {
console.log(i);
}
}
数组去重
// 使用 Set
function unique(arr) {
return [...new Set(arr)];
}
// 使用 filter
function unique2(arr) {
return arr.filter((item, index) => arr.indexOf(item) === index);
}
// 使用 reduce
function unique3(arr) {
return arr.reduce((acc, item) => {
if (!acc.includes(item)) {
acc.push(item);
}
return acc;
}, []);
}
console.log(unique([1, 2, 2, 3, 3, 3])); // [1, 2, 3]
小结
本章我们学习了:
- if...else 条件语句
- switch 语句
- 三元运算符
- for 循环
- for...in 和 for...of 循环
- while 和 do...while 循环
- break 和 continue 语句
- 循环的嵌套使用
练习
- 编写一个函数,判断一个年份是否为闰年
- 使用循环计算 1 到 100 的和
- 打印九九乘法表
- 使用 for...of 遍历数组并计算所有元素的平均值
- 编写一个函数,判断一个字符串是否是回文(正读和反读都一样)