跳到主要内容

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]

小结

本章我们学习了:

  1. if...else 条件语句
  2. switch 语句
  3. 三元运算符
  4. for 循环
  5. for...in 和 for...of 循环
  6. while 和 do...while 循环
  7. break 和 continue 语句
  8. 循环的嵌套使用

练习

  1. 编写一个函数,判断一个年份是否为闰年
  2. 使用循环计算 1 到 100 的和
  3. 打印九九乘法表
  4. 使用 for...of 遍历数组并计算所有元素的平均值
  5. 编写一个函数,判断一个字符串是否是回文(正读和反读都一样)