循环控制 #
一、循环控制概述 #
循环控制语句用于改变循环的正常执行流程。Deno提供了break、continue和标签语句来控制循环。
二、break语句 #
2.1 基本用法 #
break语句用于立即退出循环:
typescript
for (let i = 0; i < 10; i++) {
if (i === 5) {
break;
}
console.log(i);
}
// 输出:0 1 2 3 4
2.2 在while中使用 #
typescript
let count = 0;
while (true) {
console.log(count);
count++;
if (count >= 5) {
break;
}
}
// 输出:0 1 2 3 4
2.3 查找元素 #
typescript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let found: number | undefined;
for (const num of numbers) {
if (num > 5) {
found = num;
break;
}
}
console.log(found); // 6
2.4 验证数据 #
typescript
function hasInvalidNumber(numbers: number[]): boolean {
for (const num of numbers) {
if (num < 0 || num > 100) {
return true;
}
}
return false;
}
console.log(hasInvalidNumber([1, 2, 3])); // false
console.log(hasInvalidNumber([1, -1, 3])); // true
三、continue语句 #
3.1 基本用法 #
continue语句用于跳过当前迭代,继续下一次迭代:
typescript
for (let i = 0; i < 5; i++) {
if (i === 2) {
continue;
}
console.log(i);
}
// 输出:0 1 3 4
3.2 过滤数据 #
typescript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log("奇数:");
for (const num of numbers) {
if (num % 2 === 0) {
continue;
}
console.log(num);
}
// 输出:1 3 5 7 9
3.3 跳过无效数据 #
typescript
const data = [
{ id: 1, name: "Alice" },
{ id: 2, name: "" },
{ id: 3, name: "Charlie" },
null,
{ id: 4, name: "Diana" }
];
for (const item of data) {
if (!item || !item.name) {
continue;
}
console.log(`${item.id}: ${item.name}`);
}
// 输出:1: Alice 3: Charlie 4: Diana
3.4 处理文件行 #
typescript
const lines = [
"# 注释行",
"",
"hello world",
" ",
"foo bar",
"# 另一个注释"
];
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) {
continue;
}
console.log(trimmed);
}
// 输出:hello world foo bar
四、标签语句 #
4.1 基本语法 #
typescript
labelName: {
// 代码块
}
labelName: for (...) {
// 循环
}
4.2 跳出嵌套循环 #
typescript
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}`);
}
}
// 输出:i: 0, j: 0 i: 0, j: 1 i: 0, j: 2 i: 1, j: 0
4.3 继续外层循环 #
typescript
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (j === 1) {
continue outer;
}
console.log(`i: ${i}, j: ${j}`);
}
}
// 输出:i: 0, j: 0 i: 1, j: 0 i: 2, j: 0
4.4 查找二维数组 #
typescript
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
function findInMatrix(matrix: number[][], target: number): [number, number] | null {
let result: [number, number] | null = null;
search: for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] === target) {
result = [i, j];
break search;
}
}
}
return result;
}
console.log(findInMatrix(matrix, 5)); // [1, 1]
4.5 标签代码块 #
typescript
function processData(data: string): string | null {
let result: string | null = null;
process: {
if (!data) {
break process;
}
const trimmed = data.trim();
if (!trimmed) {
break process;
}
result = trimmed.toUpperCase();
}
return result;
}
console.log(processData(" hello ")); // "HELLO"
console.log(processData("")); // null
五、return替代break #
5.1 在函数中使用return #
typescript
function findFirst<T>(arr: T[], predicate: (item: T) => boolean): T | undefined {
for (const item of arr) {
if (predicate(item)) {
return item;
}
}
return undefined;
}
const numbers = [1, 2, 3, 4, 5];
const firstEven = findFirst(numbers, n => n % 2 === 0);
console.log(firstEven); // 2
5.2 提前退出 #
typescript
function processArray(arr: number[]): number {
if (arr.length === 0) {
return 0;
}
let sum = 0;
for (const num of arr) {
if (num < 0) {
return -1;
}
sum += num;
}
return sum;
}
六、实际应用 #
6.1 表单验证 #
typescript
interface FormData {
username: string;
email: string;
password: string;
}
function validateForm(data: FormData): { valid: boolean; error?: string } {
const fields: Array<{ key: keyof FormData; value: string; rules: Array<(v: string) => string | null> }> = [
{
key: "username",
value: data.username,
rules: [
v => v.length < 3 ? "用户名至少3个字符" : null,
v => !/^[a-zA-Z0-9_]+$/.test(v) ? "用户名只能包含字母、数字和下划线" : null
]
},
{
key: "email",
value: data.email,
rules: [
v => !v.includes("@") ? "邮箱格式不正确" : null
]
},
{
key: "password",
value: data.password,
rules: [
v => v.length < 8 ? "密码至少8个字符" : null
]
}
];
for (const field of fields) {
for (const rule of field.rules) {
const error = rule(field.value);
if (error) {
return { valid: false, error: `${field.key}: ${error}` };
}
}
}
return { valid: true };
}
6.2 分批处理 #
typescript
async function processInBatches<T>(
items: T[],
batchSize: number,
processor: (batch: T[]) => Promise<void>
): Promise<void> {
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
await processor(batch);
}
}
6.3 带超时的轮询 #
typescript
async function pollWithTimeout(
checkFn: () => Promise<boolean>,
options: { interval?: number; timeout?: number } = {}
): Promise<boolean> {
const { interval = 1000, timeout = 30000 } = options;
const startTime = Date.now();
while (true) {
if (await checkFn()) {
return true;
}
if (Date.now() - startTime >= timeout) {
return false;
}
await new Promise(resolve => setTimeout(resolve, interval));
}
}
6.4 游戏循环 #
typescript
interface GameState {
running: boolean;
score: number;
}
async function gameLoop(state: GameState): Promise<void> {
while (state.running) {
// 更新游戏状态
state.score++;
// 渲染
console.log(`Score: ${state.score}`);
// 延迟
await new Promise(resolve => setTimeout(resolve, 100));
// 检查结束条件
if (state.score >= 10) {
state.running = false;
}
}
console.log("Game Over!");
}
七、最佳实践 #
7.1 避免深层嵌套 #
typescript
// 不推荐
for (const a of arrA) {
for (const b of arrB) {
for (const c of arrC) {
if (condition) {
// 处理
}
}
}
}
// 推荐:使用提前退出或提取函数
function processItem(a: TypeA, b: TypeB, c: TypeC): boolean {
if (!condition) {
return false;
}
// 处理
return true;
}
7.2 使用数组方法 #
typescript
// 使用循环
const result: number[] = [];
for (const num of numbers) {
if (num > 5) {
result.push(num * 2);
}
}
// 使用数组方法
const result2 = numbers
.filter(num => num > 5)
.map(num => num * 2);
7.3 避免无限循环 #
typescript
// 危险:可能无限循环
while (true) {
// 忘记break条件
}
// 安全:设置最大迭代次数
let iterations = 0;
const maxIterations = 1000;
while (condition && iterations < maxIterations) {
// 处理
iterations++;
}
八、总结 #
本章学习了:
- break语句退出循环
- continue语句跳过迭代
- 标签语句控制嵌套循环
- return替代break
- 实际应用场景
- 最佳实践
下一章,我们将学习函数。
最后更新:2026-03-28