首页
/ freeCodeCamp Basic JavaScript 教程:用 Chaining If Else Statements(链式 if/else)实现区间分级逻辑

freeCodeCamp Basic JavaScript 教程:用 Chaining If Else Statements(链式 if/else)实现区间分级逻辑

2026-09-07 19:50:45作者:鲍丁臣Ursa

本篇文章深入剖析 freeCodeCamp 开源课程中 JavaScript 算法与数据结构认证路径下的经典编程挑战 Chaining If Else Statements(链式 if/else 语句),以 官方挑战文档 为主体,完整讲解链式分支的伪代码模板、testSize 区间分级实战需求、全部自动校验规则(hints)与官方参考解法,并延伸到 freeCodeCamp 该区块(block)内前后课程的衔接关系。读完你将掌握如何用 if / else if / else 链表达"从上到下逐级匹配"的多区间判断逻辑,并能独立通过测试运行验证自己的解答。

一、课程定位:这是 Basic JavaScript 分支结构链路的关键一环

在 freeCodeCamp 的 JavaScript 课程体系中,条件判断按难度递进地组织在同一个 block 内。通过查看区块元数据文件 curriculum/structure/blocks/basic-javascript.json(该挑战记录出现在约 L298-L301),可以看到 Chaining If Else Statements(id: 56533eb9ac21ba0edf2244dc)所处的前后顺序:

  • Introducing Else Statements —— 认识最基本的 else
  • Introducing Else If Statements挑战文档)—— 认识 else if 串联,把多个独立 if 重构为一条 else if 链;
  • Logical Order in If Else Statements —— 讨论判断条件的书写顺序对结果的影响;
  • Chaining If Else Statements(本课) —— 正式用链式分支实现"多区间映射到多结果"的分级函数;
  • Golf Code挑战文档)—— 把链式 if/else 应用到"按标准杆与杆数返回球友昵称"的真实场景;
  • 之后课程再引入 switch 系列,并在 Replacing If Else Chains with Switch 中对比两种写法的取舍。

换句话说,本课是你把"单个 if 分支"升级为"一整条可处理复杂逻辑的分支链"的实战起点。原文档对这种结构的定位非常明确:多个 if/else 可以串联在一起,以表达更复杂的逻辑

二、语法基础:一条链式 if / else if 的伪代码模板

原文档先给出了一段 pseudocode(伪代码),它是理解链式判断结构的核心骨架:

if (condition1) {
  statement1
} else if (condition2) {
  statement2
} else if (condition3) {
  statement3
}
. . .
} else {
  statementN
}

阅读这段模板需要抓住四个要点:

  1. 从上到下逐条求值:程序先判断 condition1,为真则执行 statement1,随后跳过整条链中其余所有分支;为假则继续判断 condition2,依此类推。
  2. else if 的本质else if 并不是一个独立的新关键字,而是"else 分支里再嵌套一个 if"的语法糖写法。它把嵌套结构压平成一串可读性很高的分支,这正是上一课 Introducing Else If Statements 训练的内容。
  3. 末尾兜底的 else:当所有条件都不成立时,执行最后的 else 分支。它通常用于覆盖"排除法剩下的情况",保证函数在任意输入下都有确定结果。
  4. 最多只命中一条:与多个互不相关的独立 if 不同,链式结构保证最多只有一个分支体被执行——这是区间分级逻辑正确的前提。

三、实战需求:把数值区间映射到 Tiny / Small / Medium / Large / Huge

原文档 --instructions-- 给出的题目非常典型:补全函数 testSize,使其能够把传入的 num 映射到五个从小到大依次递增的档位。五个条件的边界必须连续且不重叠

条件(按书写顺序) 应返回的字符串 覆盖的数值区间
num < 5 Tiny num = 0 ~ 4(小于 5)
num < 10 Small num = 5 ~ 9
num < 15 Medium num = 10 ~ 14
num < 20 Large num = 15 ~ 19
num >= 20 Huge num >= 20(大于等于 20)

注意最后一档使用的是 num >= 20 而不是再写一个上界,它正好承接了前四个 < 条件排除后剩余的所有情形。这也呼应了 block 中 Logical Order in If Else Statements 一课强调的核心:链式判断中条件顺序决定语义。如果这里把顺序写反(例如先判断 num < 20),那么所有小于 20 的输入都会提前落入错误分支,后续档位将永远不可达。

起点代码(--seed--)

编辑器默认给出的起点代码如下,你只能在注释标记之间修改:

function testSize(num) {
  // Only change code below this line


  return "Change Me";
  // Only change code above this line
}

testSize(7);

起点代码做三件事:声明函数 testSize(num)、提供一个占位的 return "Change Me"、并在文件末尾调用一次 testSize(7) 便于在控制台观察输出。你的任务是用一条链式 if / else if / else 替换掉占位返回语句,使不同区间的 num 返回对应的字符串。

四、自动校验规则(hints):测试如何验证你的代码

freeCodeCamp 的每个挑战都内置了由 assert 组成的测试断言(记录在文档的 --hints-- 区段)。本课的校验分两组:一组做结构上的静态检查,另一组做针对不同输入的行为测试

结构静态检查要求你的解答必须满足:

  • 至少出现 4 个 elseassert(__helpers.removeJSComments(code).match(/else/g).length > 3)。由于一共需要 4 个 else if 加 1 个收尾 elseelse 关键字总数必然大于 3。
  • 至少出现 4 个 ifassert(__helpers.removeJSComments(code).match(/if/g).length > 3)。4 个 else if 分支各带一个 if,加上起始的 if,至少应有 5 个 if
  • 至少出现 1 个 returnassert(__helpers.removeJSComments(code).match(/return/g).length >= 1),即函数必须真正把结果返回出去。

值得说明的是,这些断言在统计前会先经过 __helpers.removeJSComments(code) 把注释剥离,避免把出现在注释或字符串中的关键字误计为代码结构;随后用正则匹配 elseifreturn 的个数来"强制"你使用真实的链式写法,而不是通过投机取巧的方式绕过题目意图。

行为测试则对一组精心挑选的边界值逐一带入断言,覆盖了每个档位的下界与上界,只要区间逻辑或边界写错其中一个就会被判失败:

调用 期望返回 覆盖含义
testSize(0) 'Tiny' 下界 0
testSize(4) 'Tiny' num < 5 的上边界 4
testSize(5) 'Small' num < 10 的下边界 5
testSize(8) 'Small' 区间中部 8
testSize(10) 'Medium' num < 15 的下边界 10
testSize(14) 'Medium' num < 15 的上边界 14
testSize(15) 'Large' num < 20 的下边界 15
testSize(17) 'Large' 区间中部 17
testSize(20) 'Huge' num >= 20 的下边界 20
testSize(25) 'Huge' 更大值 25

从这组数据可以总结出三条实战经验:

  • 边界成对出现:4 与 5、9(由 Small 上界隐含)、14 与 15、19 与 20,验证了各档位临界点不能有"缝隙"也不能"重叠";
  • 区间内部抽样:8、17 等中间值用来防止你把条件写成了 num === x 这种点判断;
  • 大数兜底:25 确保 Huge>= 分支确实覆盖了所有剩余输入。

五、参考解法(--solutions--):逐层推演

官方参考解法如下:

function testSize(num) {
  if (num < 5) {
    return "Tiny";
  } else if (num < 10) {
    return "Small";
  } else if (num < 15) {
    return "Medium";
  } else if (num < 20) {
    return "Large";
  } else {
    return "Huge";
  }
}

num = 12 手动走一遍执行流:

  1. 12 < 5 为假,跳过;
  2. 12 < 10 为假,跳过;
  3. 12 < 15 为真,执行 return "Medium",函数立即返回,后续分支不再求值

这正是链式结构的精妙之处:每一个 else if 都在隐式地表达"前面的条件都不成立,并且当前条件成立"。等价于把它改写成不含 else 的复合条件:

function testSize(num) {
  if (num < 5) {
    return "Tiny";
  }
  if (num >= 5 && num < 10) {
    return "Small";
  }
  if (num >= 10 && num < 15) {
    return "Medium";
  }
  if (num >= 15 && num < 20) {
    return "Large";
  }
  return "Huge"; // num >= 20
}

对比可见:链式写法靠控制流本身的顺序隐式携带了"下界"信息,每个分支只写一个上界条件即可,代码更短且不易写错下界;而一旦使用独立的 if 链,就必须在每个条件里重复拼接 num >= 上界 &&,一旦某行遗漏或写错,区间就会出现重叠或漏洞。这也解释了为什么上一课要求你把独立 if 改写为 else if——可读性与正确性二者兼得。

六、代码级纵深:为什么"早返回"与 else 收尾缺一不可

除了题面本身,这道题还蕴含两个值得展开的 JavaScript 习惯:

1. return 充当分支出口。 每个分支体都以 return 结束,命中即返回、不再执行后续代码,因此收尾的 else { return "Huge"; } 也可以写成不带 else 的独立 return。freeCodeCamp 后续课程专门安排了 Return Early Pattern for Functions(在区块结构中紧随本课系列出现)来讲解这种"提前返回"的防御式写法。

2. else 兜底保证函数总有返回值。 因为 num 是任意数值,最后必须有一个分支承接"所有 < 20 条件都失败"的情况,否则当 num >= 20 时函数会走到末尾返回 undefined,导致 testSize(25) 无法得到 'Huge'。这也是为什么 hints 要求 else 个数严格大于 3。

3. 条件的互斥与穷尽(partition)。 五档条件共同把整个实数轴切分成了五段互不重叠的连续区间:(-∞,5)[5,10)[10,15)[15,20)[20,+∞)。互斥保证了结果唯一,穷尽保证了任何输入都有输出——这也是后续 Golf Code挑战文档)中把 7 种杆数情形映射为 7 个字符串时使用的同一套思想。

七、本地验证:脱离答题器独立运行与测试

这道挑战本身在 freeCodeCamp 在线课程编辑器中运行,但你完全可以在本地复现全部 10 个行为断言来自测:

// 将你的解答粘贴进来
function testSize(num) {
  if (num < 5) {
    return "Tiny";
  } else if (num < 10) {
    return "Small";
  } else if (num < 15) {
    return "Medium";
  } else if (num < 20) {
    return "Large";
  } else {
    return "Huge";
  }
}

// 复刻文档 hints 中的全部行为断言
const cases = [
  [0, 'Tiny'], [4, 'Tiny'], [5, 'Small'], [8, 'Small'],
  [10, 'Medium'], [14, 'Medium'], [15, 'Large'], [17, 'Large'],
  [20, 'Huge'], [25, 'Huge']
];

let passed = true;
for (const [input, expected] of cases) {
  const actual = testSize(input);
  if (actual !== expected) {
    console.log(`testSize(${input}) 应为 '${expected}',实际得到 '${actual}'`);
    passed = false;
  }
}
console.log(passed ? '全部 10 个用例通过 ✅' : '存在失败用例,请检查边界条件与分支顺序');

把以上代码保存为 .js 文件并用 node 运行,或在任意浏览器控制台执行,即可获得与在线测试等价的反馈。建议在练习时主动补充 testSize(-1)testSize(4.9)testSize(5.1) 等非整数边界用例,进一步检验条件的健壮性——所有数值都会被 JavaScript 的比较运算符正确求值。

八、学习路径总结:从本课走向 switch 与真实项目

从区块元数据 basic-javascript.json 的排列可以看出,链式 if/else 是后续一系列分支课程的地基:紧接其后的 Golf Code 用它解决多档位映射;再往后的 Selecting from Many Options with Switch StatementsAdding a Default Option in Switch Statements 以及 Replacing If Else Chains with Switch挑战文档)则会教你何时该把"等值匹配型"的 if/else 链改写成 switch

本课的核心收获可以浓缩为一条可复用的心法:

当需要把输入分档映射为不同结果时,从最小/最特殊的区间开始书写条件,使用 if ... else if ... else 首尾相接的链,让每个分支依赖前面分支已排除的隐含前提,最后用 else 兜底,并在每个分支用 return 直接退出函数——如此写出的代码既不会出现区间漏洞,也不容易产生不可达分支,是后续编写评分系统、状态机、业务规则引擎等真实逻辑时最常调用的基本功之一。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391