首页
/ 深入解析 freeCodeCamp Basic JavaScript 课程:用 return 语句返回函数值

深入解析 freeCodeCamp Basic JavaScript 课程:用 return 语句返回函数值

2026-09-07 13:04:04作者:董斯意

本文围绕 freeCodeCamp 开源课程 Basic JavaScript 单元中的经典一课"Return a Value from a Function with Return"展开,结合当前仓库中该课程的原始挑战文件、区块结构与所属认证路径,逐层讲解 return 语句如何让函数把计算结果"送出去",并给出可运行的完整解题代码、自动化判定逻辑与延伸阅读路径。读完本文,你既能吃透"参数传入、返回值传出"的函数工作模型,也能直接上手完成 timesFive 挑战并通过全部测试。

本课在学习路径中的位置

本课的课程源码位于 curriculum/challenges/english/blocks/basic-javascript/56533eb9ac21ba0edf2244c2.md。挑战文件的头部元数据如下:

字段 取值 含义
id 56533eb9ac21ba0edf2244c2 挑战全局唯一标识,用于结构文件与索引
title Return a Value from a Function with Return 课程标题
challengeType 1 课程类型标记,本类课程在正文中携带 --seed--(初始代码)与 --hints--(自动化断言)两节
forumTopicId 18271 历史论坛讨论主题编号
dashedName return-a-value-from-a-function-with-return 用于生成学习路径中的短横线式路径段

通过 dashedName 可以推断它在学习站点中对应的路径形式(仓库内相邻课程文档中可看到 /learn/.../basic-javascript/... 的完整 URL 约定)。本课归属于 JavaScript Algorithms and Data Structures 认证下的 Basic JavaScript 区块,该映射记录在 curriculum/structure/superblocks/javascript-algorithms-and-data-structures.json 中。

区块内的课程顺序定义在 curriculum/structure/blocks/basic-javascript.jsonchallengeOrder 数组中,本课位于该数组下标 50 处,前后文是典型的"由浅入深"编排:

  • 下标 48:Write Reusable JavaScript with Functions(认识函数定义与调用)
  • 下标 49:Passing Values to Functions with Arguments(把值作为参数传入函数)
  • 下标 50:本课(Return a Value from a Function with Return)
  • 下标 51:Global Scope and Functions(全局作用域)
  • 下标 52、53:Local Scope and Functions、Global vs. Local Scope in Functions
  • 下标 54:Understanding Undefined Value returned from a Function
  • 下标 55:Assignment with a Returned Value(把返回值赋给变量)

也就是说,前一课解决"数据怎么进函数",本课解决"结果怎么从函数里出来",后一课立即把它接续成"取回返回值并赋值给变量",课程链设计一目了然。

核心知识:函数不仅要接收参数,还要"交出"返回值

课程的 # --description-- 直接点出主题:

我们可以用参数(arguments)把值传入函数,也可以用一条 return 语句把值从函数里发送出去。

参数解决的是输入方向的问题:函数定义时声明的形参只是占位符,函数被调用时传入的实际值(实参)会逐一绑定到形参上。而 return 解决的是输出方向的问题——计算完成后,把结果作为函数的值交还给调用它的表达式。

在没有 return(或函数体执行完毕没有命中任何 return)的情况下,函数调用本身在 JavaScript 中会被求值为 undefined。这一点在本课之后的"Understanding Undefined Value returned from a Function"一课中还会被专门考察,说明课程设计者刻意强调"没有 return 就没有真正结果"这一易错点。

示例拆解:plusThree 到底发生了什么

课程给出的示例是把整个过程压缩成三个最小要素的经典范例:

function plusThree(num) {
  return num + 3;
}

const answer = plusThree(5);

它的执行过程可以拆成四步:

  1. 定义阶段:用函数声明创建名为 plusThree 的函数,形参为 num,函数体只有一条 return num + 3;
  2. 求值实参:执行 plusThree(5) 时,实参 5 被绑定到形参 num
  3. 计算并返回:函数体求值 num + 3,得到 8return 语句立即把 8 作为整个调用表达式的结果交出去。
  4. 承接结果:调用表达式 plusThree(5) 此刻已经"变成"值 8,于是 answer 被赋值为 8

课程原文特别给出结论:answer 的值为 8plusThree 接收针对 num 的参数,并返回等于 num + 3 的新值。这里可以提炼出一个通用认知:带返回值的函数调用,本质上就是一条会产出值的表达式,它可以被赋值、参与运算,也可以继续作为另一个函数的实参。

动手任务:实现 timesFive

课程的 # --instructions-- 要求如下:

创建一个函数 timesFive,它接收一个参数,将该参数乘以 5,并返回新得到的值。

与之配套的 # --seed-- 给出了一个空白的初始代码区(即编辑器中没有任何预置代码,需要从零书写):


注意这是一个纯"从空白起步"的编写型挑战:不需要 console.log 打印,不需要修改任何全局状态,唯一要做的是定义函数并通过 return 返回乘积。

自动化判定:hints 如何验证你的答案

课程 # --hints-- 一节给出了四组断言,它们共同构成了通过标准:

断言 判定内容 类型检查要点
assert(typeof timesFive === 'function'); 必须先存在名为 timesFive 的函数 typeof 验证声明形式(函数声明、函数表达式均可)
assert(timesFive(5) === 25); 传入 5 应返回 25 验证一般乘法路径
assert(timesFive(2) === 10); 传入 2 应返回 10 验证中间取值
assert(timesFive(0) === 0); 传入 0 应返回 0 验证边界输入(零值)

注意判定样例特意覆盖了正数、小值与零三种输入。其中 timesFive(0) === 0 这条尤其能"戳穿"两类典型错误:

  • 忘记 return:若只写了 num * 5 却没有 return,函数会返回 undefined,所有断言全部失败;
  • return 后继续写了不可达语句return 一旦执行,函数立即结束,其后的语句不再执行。

参考答案与逐行讲解

课程 # --solutions-- 中给出的官方参考答案:

function timesFive(num) {
  return num * 5;
}
timesFive(10);

逐行分析:

  • 第 1 行用函数声明定义 timesFive,形参命名为 num(形参名可自由选取,与调用方的实参无关);
  • 第 2 行是解题核心:计算 num * 5 并立刻由 return 返回。这里的 num * 5先求值、后返回
  • 第 4 行 timesFive(10); 是一次主动调用,用于在实际运行环境中让函数真正执行一次(多数断言运行器不会因为"定义了但从未调用"而报错,但调用有助于在练习环境里即时看到效果)。

要特别留意第 2 行的语义:return 右侧表达式的求值发生在返回之前。这正是仓库中后一课 Assignment with a Returned Value 所强调的原理——"等号右侧的一切会先被求值,然后才完成赋值",所以函数调用的返回值可以被直接赋值给变量:

processed = processArg(7);

同理,timesFive(5) 会在调用处"就地变成"25,进而能与 ===、赋值号等一切需要值的地方协同工作。

return 的三类典型用途(本课之后的自然延伸)

掌握了本课的最小模型后,可以把 return 的使用模式归纳为三类,它们在后续课程中都会反复出现:

  1. 产出计算结果供外部使用:如 plusThreetimesFive。函数的价值在于把"计算"封装起来,让调用者拿到一个值,而不是只产生屏幕输出。
  2. 参与表达式与赋值:函数调用本身是值,因此 const answer = plusThree(5); 这类写法成立。后一课 Assignment with a Returned Value 专门训练的就是这一步。
  3. 提前退出并返回控制权:当函数在某分支上已得出结果或不应继续执行时,用 return 立即结束。Basic JavaScript 区块中下标 80 处还有一课专门名为 "Return Early Pattern for Functions",正是对该用法的专项训练。

从代码组织角度看,return 是把函数从"只会打印的脚本片段"升级为"可被复用的计算单元"的分水岭:有了返回机制,函数才能被赋值、被组合、被更复杂的程序调度,这也是 JavaScript 函数式组合的基础。

该挑战文件本身也是一种可读的仓库资源

作为 freeCodeCamp 开源课程的一部分,每个挑战的 Markdown 都遵循稳定的分节结构:# --description--(讲解)、# --instructions--(任务)、# --hints--(断言)、# --seed--(初始代码)、# --solutions--(参考答案)。初学者在本地阅读本仓库时,可以对照 basic-javascript.json 中的课程顺序,按索引逐一攻克,用 hints 中的断言当作"自带单元测试"来检验自己的实现;也可以直接阅读 --solutions-- 学习官方推荐的写法,再对比自己的代码寻找差异。这种"题目、测试与答案同仓共存"的结构,正是练习 JavaScript 基础语法最直接的本地学习素材。

小结与自查清单

完成本课的关键可归纳为三点:函数用形参接收输入、用 return 交还输出、没有 return 的函数调用值为 undefined。提交前可用下面的清单自查:

  • 是否用 function(或函数表达式)声明了名为 timesFive 的标识符?
  • 函数体是否真正书写了 return num * 5;,而不是仅仅写了 num * 5;
  • timesFive(5) 是否为 25timesFive(2) 是否为 10timesFive(0) 是否为 0
  • 是否存在 return 之后还放代码导致永远不会执行的死代码?

依次对照 本课挑战文件 中的四条 hints,全部满足即视为通过。此后沿 basic-javascript.json 的顺序继续学习全局/局部作用域、无返回值函数的 undefined 以及"赋值与返回值",即可把函数这一 JavaScript 核心概念完整打通。

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

项目优选

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