首页
/ freeCodeCamp 基础 JavaScript 课程精讲:用逻辑或运算符 `||` 合并条件分支

freeCodeCamp 基础 JavaScript 课程精讲:用逻辑或运算符 `||` 合并条件分支

2026-09-07 15:55:20作者:魏侃纯Zoe

本篇技术指南围绕 freeCodeCamp 开源课程仓库中 Basic JavaScript(基础 JavaScript)课程块(block)内"Comparisons with the Logical Or Operator"这一节展开,系统讲解 JavaScript 逻辑或运算符 || 的求值语义,以及如何用它把"多个 if 提前返回"的重复分支合并为一条单一条件判断。读完本文,你将理解 || 在区间边界判断中的正确写法(含闭区间与补集的转换),掌握区间校验类题目从题目描述、待补全代码、自动化断言到参考答案的完整解题链路。

课程在 freeCodeCamp 课程体系中的位置

本节课程是 freeCodeCamp 全栈课程体系中"JavaScript 算法与数据结构"前端学习路径的一部分。课程源码使用 Markdown + YAML frontmatter 的格式存放,本节即位于:

文件开头的 frontmatter 声明了它的元数据:

id: 56533eb9ac21ba0edf2244d9
title: Comparisons with the Logical Or Operator
challengeType: 1
forumTopicId: 16800
dashedName: comparisons-with-the-logical-or-operator
  • id 是课程块的全局唯一标识,同时被 basic-javascript.json 块结构文件 引用,用于维护每个块内部的课程顺序;
  • challengeType: 1 表示这是一道需要学习者直接编写并提交代码的编码型练习(而非测验、项目或视频讲解类题型);
  • dashedName 用于生成 URL 与文件命名的短横线形式。

从块结构文件的顺序可以确认其教学定位:它紧跟"Comparisons with the Logical And Operator"(&& 逻辑与课程,文件 56533eb9ac21ba0edf2244d8.md)之后,位于 "Introducing Else Statements"(else 语句)之前。也就是说,freeCodeCamp 的教学设计是先分别掌握 &&|| 两个逻辑运算符,再过渡到 else / else if 分支结构。

逻辑或运算符 || 的核心语义

课程正文给出了 || 的正式定义:

逻辑或(logical or)运算符(||)在任一操作数(operand)为 true 时返回 true,否则返回 false

运算符本体由两个管道符号组成:||。课程还贴心地提示了它在键盘上的物理位置——通常位于 Backspace(退格键)和 Enter(回车键)之间。这与逻辑与运算符 &&(两个与号)的键盘位置形成对称,便于初学者记忆。

其真值表如下(设 AB 为任意布尔表达式):

A B A || B
true true true
true false true
false true true
false false false

可以看到,只要两侧条件有任意一个成立,整体即为 true,只有两个条件都失败时才为 false。这正是"或"的语义:表示两种异常情形中的任何一种发生都需要处理。

问题背景:两个 if 带来的重复逻辑

课程从一道熟悉的模式切入,先展示一段未使用 || 的朴素写法:

if (num > 10) {
  return "No";
}
if (num < 5) {
  return "No";
}
return "Yes";

这段代码的逻辑是:

  • num > 10,返回 "No"
  • num < 5,返回 "No"
  • 其余情况(即 5 <= num <= 10,包含边界值 5 和 10)返回 "Yes"

课程明确指出,这段代码在 num 处于 5 到 10 之间(含两端)时返回 Yes。注意这里两个 if 都返回完全相同的字符串 "No",属于典型的重复分支——它们判断的其实是同一个逻辑结论("超出合法区间"),只是写成两个互斥的子条件。此类代码可以安全地合并。

|| 完成等价重写

上述两段互不相交的判断可以用 || 合并为一个条件,这正是课程给出的第二种写法:

if (num > 10 || num < 5) {
  return "No";
}
return "Yes";

逐步推演其语义:

  • num = 12num > 10true,短路命中,条件成立 → "No"
  • num = 3num > 10false,继续检查 num < 5true → 条件成立 → "No"
  • num = 7:两侧均为 false,整体为 false → 落到最后的 return "Yes"

合并后代码的可读性与维护性都得到提升:读者只需看一条边界条件,就能理解"超出 [5, 10] 区间即返回 No"这一完整规则,而无需在脑海中拼接两个独立 if

这里还体现了一个重要的补集(complement)思想:num 处于闭区间 [5, 10] 内时返回 "Yes",因此"返回 No"恰好是闭区间的补集,也就是 num < 5 || num > 10。题目往往喜欢用这种"反向条件"考察学习者是否理解闭区间边界是否包含端点。

本节任务:判断 val 是否落在闭区间 [10, 20] 之外

课程的指令(--instructions--)要求学习者完成一次真实的重构:

将两个 if 语句合并为一条语句。当 val 不在 10 到 20 之间(含端点)时返回字符串 Outside,否则返回字符串 Inside

初始代码(seed)提供了如下骨架,// Only change code below this line// Only change code above this line 之间是唯一的可编辑区域:

function testLogicalOr(val) {
  // Only change code below this line

  if (val) {
    return "Outside";
  }

  if (val) {
    return "Outside";
  }

  // Only change code above this line
  return "Inside";
}

testLogicalOr(15);

待解决问题一目了然:两个 if (val) 目前只是判断 val 的"真值"(truthiness),且条件重复,无论怎么调用都会返回 "Outside"——这段骨架需要用真实比较条件替换。

关键:闭区间边界如何取舍

题目措辞"not between 10 and 20, inclusive"至关重要:

  • 10 <= val <= 20 属于区间内部,应返回 "Inside"
  • 所以返回 "Outside" 的条件是补集:val < 10 val > 20

因此最小且正确的修改是补全两个 if 的比较条件,再用 || 连接:

function testLogicalOr(val) {
  // Only change code below this line

  if (val < 10 || val > 20) {
    return "Outside";
  }

  // Only change code above this line
  return "Inside";
}

testLogicalOr(15);

边界行为推演

结合仓库内 --hints-- 中的断言用例,可验证边界处理:

输入 val 条件求值 返回值
0 0 < 10 → true "Outside"
9 9 < 10 → true "Outside"
10 均 false "Inside"
15 均 false "Inside"
19 均 false "Inside"
20 均 false "Inside"
21 21 > 20 → true "Outside"
25 25 > 20 → true "Outside"

注意边界值 10 与 20 都落在区间内返回 "Inside",这正是 inclusive(含端点)要求的体现。若把条件误写成 val <= 10 || val >= 20,则 10 与 20 会被错误判为 "Outside",直接触发断言失败。

自动化校验如何工作:hints 逐条拆解

freeCodeCamp 每道练习都在 --hints-- 段中声明一系列自动化校验。本节的断言可分成两类。

第一类约束代码结构,使用正则校验代码写法:

assert(__helpers.removeJSComments(code).match(/\|\|/g).length === 1);
assert(__helpers.removeJSComments(code).match(/if/g).length === 1);

这两条断言的含义是:

  1. 学习者代码中去掉注释后,|| 必须恰好出现一次——即必须使用逻辑或运算符,且不能靠堆叠多个 || 蒙混过关;
  2. if 关键字只能出现一次——即必须完成"两个 if 合并成一个 if"的重构要求,验证了题目核心目的。

__helpers.removeJSComments(code) 会在断言前先剥离 JS 注释,避免学习者把 ||if 藏在注释中绕过结构检查。

第二类校验函数行为,通过真实调用结果比对:

assert(testLogicalOr(0) === 'Outside');
assert(testLogicalOr(9) === 'Outside');
assert(testLogicalOr(10) === 'Inside');
assert(testLogicalOr(15) === 'Inside');
assert(testLogicalOr(19) === 'Inside');
assert(testLogicalOr(20) === 'Inside');
assert(testLogicalOr(21) === 'Outside');
assert(testLogicalOr(25) === 'Outside');

8 个断言覆盖了区间内、区间外、以及两端边界共三类情形,组成一张完备的边界测试矩阵。这也从侧面说明:编写区间判断逻辑时,边界测试用例(端点值、端点相邻值、远离端点值)是不可省略的验证手段。

这些 Markdown 课程文件并非由浏览器直接渲染为题目,而是经由仓库中的 curriculum/schema/challenge-schema.js 用 Joi 模式进行结构校验(frontmatter 字段、--description----hints----seed----solutions-- 等分节是否符合规范),再在编译流水线中被解析为课程数据,供客户端(如 client/src/templates/Challenges 下的课程渲染组件)加载与评测。

官方参考答案与解题要点

--solutions-- 段给出了参考实现:

function testLogicalOr(val) {
  if (val < 10 || val > 20) {
    return "Outside";
  }
  return "Inside";
}

参考答案刻意保持单 if + 单 return 的"守卫子句(guard clause)"风格:先处理异常区间并提前返回,函数末尾作为兜底返回正常结果。这样即便后续新增其他区间判断,也能以追加守卫子句的方式保持主逻辑平铺,避免多层嵌套。

解题要点小结:

  1. 先翻译区间语义[10, 20] 内为 "Inside",则区间外即 val < 10 || val > 20
  2. 牢记 inclusive:用 <>(而非 <=>=)划定边界,确保 10、20 落在区间内;
  3. 只保留一个 if、一个 ||,以满足两条结构断言;
  4. 保持函数末尾的 return "Inside" 不变,不要删改 // Only change code 边界之外的内容。

与其他逻辑运算符的知识衔接

如果继续沿 Basic JavaScript 课程块向后学习,会发现本课与相邻课程构成了严密的逻辑链:

  • 前置课程 Comparisons with the Logical And Operator(&& 教学的是"区间内"的表示法 val >= 25 && val <= 50,而本课反其道而行,练习"区间外"的表示法 val < 10 || val > 20。二者正好互为补集,建议对照学习;
  • 后置课程 Introducing Else Statements 会引入 else 分支,届时单 if + 末尾返回的写法也可以等价改写为 if/else
  • 再往后 Chaining If Else Statements、Golf Code 等项目将把比较运算、逻辑运算与 switch 组合成真实小程序的判定逻辑。

掌握 || 后即可自然过渡到组合判断,例如"账号过期 密码错误则拒绝登录""输入为空 超过最大长度则校验失败"等真实场景,均是"区间外/异常态"集合判断的典型应用。

深入仓库:如何查看与校验这份课程文件

想在本仓库中深入学习或验证本课内容,可沿以下路径:

  1. 课程正文curriculum/challenges/english/blocks/basic-javascript/56533eb9ac21ba0edf2244d9.md——即本文讲解的源文件,含描述、指令、断言与种子代码;
  2. 课程顺序curriculum/structure/blocks/basic-javascript.json——确认 && 课、|| 课与 else 课的排列关系(本课的 id 在文件的 challengeOrder 中与标题对应);
  3. 格式校验curriculum/schema/challenge-schema.js——Joi schema 定义了上述 Markdown 课程文件的合法结构,是所有课程 Markdown 入库前的质量闸门;
  4. 相邻参考:与本课结构几乎完全同构的 Logical And 课文件 可作为对照模板,体会两课描述、种子、断言与答案的对称设计。

课程内容属纯前端 JavaScript 范畴,无需安装额外依赖即可在任意浏览器控制台或 Node REPL 中手工验证 testLogicalOr 的输出;若要运行仓库自带的课程结构校验,则需按仓库根目录 README.md 中的说明安装依赖并执行对应的工作区脚本。这种"Markdown 定义内容 + Joi 定义结构 + 断言矩阵验收"三位一体的设计,是 freeCodeCamp 大规模开源课程得以保持质量一致性的关键机制,也是学习课程工程化组织的绝佳范例。

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

项目优选

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