首页
/ freeCodeCamp JavaScript 基础教程精讲:严格相等运算符(`===`)与类型安全比较实战

freeCodeCamp JavaScript 基础教程精讲:严格相等运算符(`===`)与类型安全比较实战

2026-09-07 23:28:09作者:邵娇湘

本指南以 freeCodeCamp 开源课程 Basic JavaScript(JavaScript 基础)区块中的一关挑战为切入点,系统讲解严格相等运算符 === 与宽松相等运算符 == 的差异、隐式类型转换机制,并结合仓库中的关卡文档逐条拆解题面、验证脚本与标准答案,帮助你准确掌握类型敏感的条件判断写法。读完本文,你将能独立完成该关卡,并理解相等判断中"类型不转换"这一核心语义及其在 if 语句、参数校验中的实战意义。

关卡背景:它在 Basic JavaScript 课程中的位置

本文所讲解的挑战文档位于仓库的 curriculum/challenges/english/blocks/basic-javascript/ 目录,文件名以挑战 ID 56533eb9ac21ba0edf2244d1 命名,即 comparison-with-the-strict-equality-operator.md。该文件的 frontmatter 记录如下元数据:

字段 含义
id 56533eb9ac21ba0edf2244d1 挑战全局唯一 ID,同时也是文件名
title Comparison with the Strict Equality Operator 关卡标题
challengeType 1 挑战类型(1 代表普通编码挑战)
forumTopicId 16790 论坛讨论主题 ID
dashedName comparison-with-the-strict-equality-operator 用于 URL 的短横线命名

从区块结构文件 curriculum/structure/blocks/basic-javascript.json 可以确认它的排课顺序:关卡 ...d0Comparison with the Equality Operator,比较运算符 ==)在前,紧接着就是本关 ...d1(严格相等运算符),其后依次是 ...d2 不等运算符 !=...d3 严格不等运算符 !== 以及 ...d4 大于运算符 >。也就是说,freeCodeCamp 刻意将"普通相等/严格相等/普通不等/严格不等"四关连排,让学习者先理解宽松比较,再理解类型敏感的严格比较,形成完整的对比认知链。

核心概念:严格相等 === 不做类型转换

本关 --description-- 部分给出的定义非常精炼:严格相等运算符(===)是相等运算符(==)的对应物,但与会在比较前尝试把两个值转换为公共类型的 == 不同,=== 不执行任何类型转换

由此可以直接推导出两条规则:

  1. 若参与比较的两个值类型不同,它们会被视为不相等,=== 返回 false
  2. 只有当类型相同且值也相等时,=== 才返回 true

关卡给出的示例代码:

3 ===  3  // true
3 === '3' // false

第二个表达式中,3 属于 Number 类型,'3' 属于 String 类型,类型不同,故严格比较直接判定不相等并返回 false

对比前一关 comparison-with-the-equality-operator.md== 的行为,差异一目了然:

1   ==  1  // true
1   ==  2  // false
1   == '1' // true   // 数字 1 与字符串 '1' 被视为相等
"3" ==  3  // true   // 字符串 "3" 与数字 3 被视为相等

== 之所以让 1 == '1' 成立,是因为它触发了 JavaScript 的隐式类型转换(Type Coercion),先把一方转换成另一方的类型再比较;而 === 直接跳过这一步骤,类型不一致即判定不相等。关卡文档也特别提醒:相等比较(equality)不同于赋值(assignment)——= 是把右侧值赋给左侧变量,初学者常混淆这一点。

与严格不等运算符 !== 的逻辑互补

为了把比较运算符家族讲透,本区块还安排了与之配对的严格不等运算符。文档 comparison-with-the-strict-inequality-operator.md 明确指出:严格不等运算符(!==)是严格相等运算符(===)的逻辑对立面,含义是"严格不相等",在严格相等返回 true 的地方它返回 false,反之亦然,并且同样不进行任何类型转换

3 !==  3  // false
3 !== '3' // true
4 !==  3  // true

也就是说,一旦你掌握了 === 的类型敏感语义,!== 就是它的镜像:类型不同直接判为不相等(返回 true),类型相同则看值是否不同。而普通不等运算符 !=(见 comparison-with-the-inequality-operator.md)与 == 一样会做类型转换,例如 1 != "1" 返回 false1 != true 返回 false

把这四个运算符放在一起对比:

表达式 ==(宽松) ===(严格) !=(宽松) !==(严格)
3 vs 3 true true false false
3 vs '3' true(发生类型转换) false(类型不同) false true
1 vs true true(布尔被转换) false false true

实战关卡:让函数只在 val 严格等于 7 时返回 "Equal"

任务要求(Instructions)

本关 --instructions-- 给出的任务是:在 if 语句中使用严格相等运算符,使函数在 val 严格相等7 时返回字符串 Equal

题目对返回值有两个关键限定:其一,返回的是字符串 "Equal" / "Not Equal" 而非布尔值;其二,比较基准值是数字 7,而测试用例会额外传入字符串 "7",以此检验你是否真的用了 ===——如果误用 =="7" 会被转换成数字与 7 相等,函数就会错误地返回 "Equal"

初始代码(Seed Code)

关卡提供了如下带占位符的骨架代码,待修改行已被注释标出:

// Setup
function testStrict(val) {
  if (val) { // Change this line
    return "Equal";
  }
  return "Not Equal";
}

testStrict(10);

注意初始代码中的 if (val) 是一个真值性判断:它只检查 val 是否为真值(truthy),而非与 7 比较。JavaScript 中 107、非空字符串等都是真值,因此目前无论传入 107 还是 "7",条件都成立,函数一律返回 "Equal"。这正是本关的训练点——你必须把它改造成与固定值 7 的严格比较。

逐条拆解验证脚本(Hints)

课程对每个关卡都内置了自动化验证(assert)。本关 hints 共四条,恰好构成完整的等价类测试用例:

assert(testStrict(10) === 'Not Equal');   // 数字 10 ≠ 7,且与 7 同类型但值不同 → Not Equal
assert(testStrict(7) === 'Equal');        // 数字 7 与数字 7 同类型且同值 → Equal
assert(testStrict('7') === 'Not Equal');  // 字符串 '7' 与数字 7 类型不同 → Not Equal(严格比较的关键用例)
assert(__helpers.removeJSComments(code).match(/(val\s*===\s*\d+)|(\d+\s*===\s*val)/g).length > 0);

前三条分别验证:不相等数字应返回 "Not Equal"、相等数字应返回 "Equal"同值的字符串 '7' 必须返回 "Not Equal"。第三条是整个关卡的灵魂——如果使用 =='7' == 7 会因类型转换而成立,测试将失败;只有 === 才能让同值不同类型被判为不相等。

第四条是源码级约束校验:先调用 __helpers.removeJSComments(code) 剔除代码中的注释,再用正则 (val\s*===\s*\d+)|(\d+\s*===\s*val) 匹配源码中是否真的出现了形如 val === 数字(或反向书写)的严格相等比较。这条断言从文本层面杜绝了学习者绕过题目、直接写死返回值的取巧做法——因为你的代码里必须真实存在 === 7 的比较表达式。

标准答案与讲解

关卡自带的 --solutions-- 段给出了参考实现:

function testStrict(val) {
  if (val === 7) {
    return "Equal";
  }
  return "Not Equal";
}

求解思路分两步:

  1. if (val) 的真值性判断替换为 if (val === 7),明确比较对象与比较基准;
  2. 保留函数的双分支返回结构:条件成立返回 "Equal",否则(包括 10'7'"bob" 等各种其他值)落入 return "Not Equal"

可以自行用 testStrict(10)testStrict(7)testStrict("7") 依次调用验证,输出应分别为 "Not Equal""Equal""Not Equal",与 hints 断言完全一致。

深入理解:为什么类型敏感的比较更可靠

结合仓库内后续 Workshop 型课程(如 learn-introductory-javascript-by-building-a-pyramid-generator 等同样大量使用比较运算符的关卡)可以看出,freeCodeCamp 在整条 JavaScript 教学线中持续强调相等判断。从工程实践角度,推荐优先使用 ===/!== 的理由非常充分:

  • 消除隐式转换带来的意外0 == false'' == 0null == undefined 等宽松比较结果常与直觉相悖,是许多隐蔽 bug 的来源;=== 让"比较什么类型"完全显式化;
  • 匹配主流编码规范与 lint 工具:多数团队和 ESLint 推荐配置默认开启 eqeqeq 规则,强制使用严格相等;
  • 代码自文档化val === 7 一眼即可读出"值是数字 7",而 val == 7 则暗示"某个会被转换成数字 7 的值"。

不过也需客观说明,== 并非一无是处:当你想同时匹配 nullundefined 时,value == null 是常见写法。理解两者差异后,就能在"显式严格"与"刻意宽松"之间做出有意识的选择——这正是本关要培养的判力。

如何在本地查看与学习本关

当前仓库是只读的课程源码,你可以直接浏览以下路径深入学习:

在浏览器中打开 freeCodeCamp 学习平台进入 Basic JavaScript 区块,即可看到该关卡并以在线编辑器作答;在本地则可将上述解答函数粘贴进 Node.js 环境运行 node 文件名.js 验证结果。关卡 MD 文件的 frontmatter 与 --description----instructions----hints----seed-contents----solutions-- 分段结构,本身就是一种机器可读的课程内容格式,社区贡献者正是通过维护这些 Markdown 源文件来持续更新全球学习者的课程体验。

小结

围绕 freeCodeCamp 的 "Comparison with the Strict Equality Operator" 这一关,本文覆盖了三层内容:语义层上,=== 不做类型转换、类型不同即判不相等;实操层上,通过把 if (val) 改造为 if (val === 7) 并对照四条断言理解等价类测试设计;对比层上,用 =====!=!== 四个运算符的对照表厘清宽松与严格两条比较路线。掌握 === 意味着你在写条件逻辑时多了一分确定性——这在处理用户输入、表单校验与函数参数判断等真实场景中,都是绕不开的基本功。

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

项目优选

收起
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