首页
/ Web-Dev-For-Beginners「Fun with Functions」作业全解:JavaScript 函数定义、默认参数与返回值实战

Web-Dev-For-Beginners「Fun with Functions」作业全解:JavaScript 函数定义、默认参数与返回值实战

2026-09-06 11:41:57作者:冯梦姬Eddie

本文为 Web-Dev-For-Beginners 课程第 2 章(JavaScript 基础)第 2 课「Functions and Methods」的配套作业实战指南,完整覆盖作业文档 assignment.md 中的全部 6 个函数任务、示例测试调用与评分细则(Rubric),并给出可直接运行的完整参考答案、预期控制台输出,以及基于课程 README 中函数语法、参数、默认值、返回值与高阶函数等概念逐项对位的讲解,读完后你能独立完成从函数声明到测试验证的完整流程,并通过全部考核项。

JavaScript 函数课节手绘知识图谱

一、作业定位:它在整个 JavaScript 基础课程中的位置

本作业属于 2-js-basics 课程目录下的第 2 课,该课程按「变量与数据类型 → 函数与方法 → 决策 → 数组与循环」四步展开。函数一课时对应课程的第二个里程碑:从「认识数据」过渡到「组织代码逻辑」。

对应课程文档(2-js-basics/2-functions-methods/README.md)的核心知识点,与作业考查点的对应关系如下:

课程知识点 对应作业任务
函数声明与调用(function name() {} + 括号调用) Part 1:sayHellointroduceYourself
参数(Parameters)与实参(Arguments) Part 1–4 全部涉及参数的函数
默认参数(Default Parameters) Part 2:greetPerson;Part 4:calculateTip
返回值(Return Values) Part 3:addNumberscreateFullName;Part 4:calculateTip
模板字符串(Template Literals,反引号 + ${} Part 1 的日志输出、Part 5 的测试调用
高阶函数(函数作为参数) Bonus Challenge 2

需要特别区分的一个概念(也是课程「Challenge」部分要求一句话说清的问题):函数(function)是独立的代码块,而方法(method)是挂在对象上的函数。作业末尾提示中让你按 F12 打开浏览器开发者控制台查看 console.log() 的输出——console.log 本身就是一个方法(属于 console 对象),这恰好印证了课程文档中的说明。

二、任务总览:五个部分、六个函数

作业原文要求在名为 functions-practice.js 的 JavaScript 文件中实现以下 6 个函数,分为五个部分:

部分 任务 函数名 参数 行为
Part 1 基础函数 1 sayHello 向控制台打印 "Hello!"
Part 1 基础函数 2 introduceYourself name 打印类似 "Hi, my name is [name]" 的消息
Part 2 默认参数 3 greetPerson name(必填)、greeting(可选,默认 "Hello" 打印类似 "[greeting], [name]!" 的消息
Part 3 返回值 4 addNumbers num1num2 返回两数之和
Part 3 返回值 5 createFullName firstNamelastName 返回合并后的完整姓名(单个字符串)
Part 4 综合运用 6 calculateTip billAmount(必填)、tipPercentage(可选,默认 15) 计算并返回小费金额

Part 5 则要求为以上每个函数添加测试调用,并用 console.log() 展示结果。作业给出的示例测试代码如下(原样保留自 assignment.md):

// Test your functions here
sayHello();
introduceYourself("Sarah");
greetPerson("Alex");
greetPerson("Maria", "Hi");

const sum = addNumbers(5, 3);
console.log(`The sum is: ${sum}`);

const fullName = createFullName("John", "Doe");
console.log(`Full name: ${fullName}`);

const tip = calculateTip(50);
console.log(`Tip for $50 bill: $${tip}`);

这组测试调用暗含三个考点:greetPerson 分别以 1 个和 2 个实参调用(验证默认值是否生效);addNumberscreateFullNamecalculateTip 的返回值被存入 const 变量后再打印(验证「返回而非打印」的区分);calculateTip(50) 只传账单金额,验证 tipPercentage 是否按 15% 计算。

三、完整参考答案:functions-practice.js

下面给出可整体复制运行的完整参考实现,按作业的五个部分组织,并逐项标注其对应课程文档中的语法要点:

// functions-practice.js

// ========== Part 1: Basic Functions ==========

// 无参数函数:function 关键字 + 名称 + 括号 + 花括号函数体
function sayHello() {
  console.log("Hello!");
}

// 单参数函数:name 是参数(形参),调用时传入的值是实参
function introduceYourself(name) {
  console.log(`Hi, my name is ${name}`);
}

// ========== Part 2: Functions with Default Parameters ==========

// greeting 带默认值 "Hello":调用时省略该实参即取默认值
function greetPerson(name, greeting = "Hello") {
  console.log(`${greeting}, ${name}!`);
}

// ========== Part 3: Functions that Return Values ==========

function addNumbers(num1, num2) {
  return num1 + num2;
}

function createFullName(firstName, lastName) {
  return `${firstName} ${lastName}`;
}

// ========== Part 4: Mix It All Together ==========

// 必填参数 + 可选默认参数 + 返回值,三合一
function calculateTip(billAmount, tipPercentage = 15) {
  return billAmount * (tipPercentage / 100);
}

// ========== Part 5: Test Your Functions ==========

sayHello();
introduceYourself("Sarah");
greetPerson("Alex");
greetPerson("Maria", "Hi");

const sum = addNumbers(5, 3);
console.log(`The sum is: ${sum}`);

const fullName = createFullName("John", "Doe");
console.log(`Full name: ${fullName}`);

const tip = calculateTip(50);
console.log(`Tip for $50 bill: $${tip}`);

运行方式与预期输出

作业提示(Tip)指出,可在浏览器开发者控制台(按 F12 打开)中查看 console.log() 的输出——例如把脚本贴进控制台的 Console 面板执行即可。另外,由于脚本没有依赖 DOM,也可以直接在 Node.js 环境中运行:

node functions-practice.js

预期控制台输出为:

Hello!
Hi, my name is Sarah
Hello, Alex!
Hi, Maria!
The sum is: 8
Full name: John Doe
Tip for $50 bill: $7.5

逐行对位说明:

  • sayHello()Hello!(函数体直接 console.log,无返回值);
  • introduceYourself("Sarah") → 实参 "Sarah" 绑定到参数 name,模板字符串插值后输出;
  • greetPerson("Alex") → 未提供第二个实参,greeting 取默认值,输出 Hello, Alex!
  • greetPerson("Maria", "Hi") → 显式传入 "Hi" 覆盖默认值;
  • addNumbers(5, 3) 返回 8,经 The sum is: ${sum} 打印;
  • createFullName("John", "Doe") 返回单个字符串 John Doe
  • calculateTip(50) 按默认 15% 计算:50 * (15 / 100) = 7.5

四、逐项解析:作业背后考查的语法机制

以下解析基于课程文档 2-js-basics/2-functions-methods/README.md 的讲解脉络,帮助理解每个任务「为什么这么写」。

4.1 Part 1:函数声明与调用的最小完整形态

课程文档给出的声明语法模板是 function nameOfFunction() { /* body */ },四个组成部分分别是:

  • function 关键字:声明意图;
  • 函数名:应使用能自解释意图的描述性名称(课程文档举例 cancelTimer(),且约定多词名称用 camelCasing,如 calculateTotal 而非 calculate_total);
  • 圆括号 ():参数列表所在(Part 1 的 sayHello 为空);
  • 花括号 {}:函数体,调用时才执行。

调用时必须带括号——写 displayGreeting 而不带 () 只会取到函数引用而不会执行函数体,这是课程文档「Function Fundamentals Check」自查清单中的问题之一。定义与调用的先后顺序不受限制,JavaScript 引擎会处理执行顺序。

4.2 Part 2:默认参数如何让函数「向前兼容」

greetPerson(name, greeting = "Hello") 对应课程文档的「Default values」小节。文档用几乎同构的例子(displayGreeting(name, salutation='Hello'))说明:默认值写法与普通变量赋值一样用等号;第一个实参缺失时取默认值,传入时则覆盖默认值。文档强调这种设计的价值在于调用者可以低成本上手(合理默认值),又保留定制能力,且旧调用方式无需修改(向后兼容)。

注意一个细节:默认参数必须放在必填参数之后。若写成 greetPerson(greeting = "Hello", name),则只传一个实参时该值会绑定给 greeting,语义立刻错乱——这正是 Rubric 中「Parameters & Default Values」项区分 Exemplary 与 Needs Improvement 的地方之一。

4.3 Part 3:返回值 vs 打印——两种截然不同的函数契约

Part 3 是作业中区分度最高的一部分。addNumberscreateFullName 的共同点是「计算并交还结果」,而不是「把结果显示在控制台」:

function addNumbers(num1, num2) {
  return num1 + num2;
}

课程文档对此有两条关键说明,均直接决定了本部分能否得满分(Rubric 的「Return Values」项):

  1. return 立即终止函数执行,并把值交回给调用者;return 之后的代码不会运行;
  2. 没有 return 的函数返回 undefined,这类函数只产生副作用(如打印日志、修改 DOM)。

由此可以对照作业的任务划分:Part 1/2 的三个函数(sayHellointroduceYourselfgreetPerson)是「只执行动作」型,Part 3/4 的三个函数(addNumberscreateFullNamecalculateTip)是「交还数据」型。混淆两类契约的典型错误是:在 addNumbers 里写 console.log(num1 + num2) 而没有 return——此时测试代码中的 const sum = addNumbers(5, 3) 会拿到 undefined,输出变成 The sum is: undefined,正好可以通过 Part 5 的测试暴露问题。

返回值的用途也由此展开:存入变量(如 const fullName = ...)、参与表达式、传给另一个函数。返回的也可以是任意类型(字符串、数字、布尔、对象、数组),课程文档的「Return Value Types」图统计了常见返回类型分布。

4.4 Part 4:默认参数 + 返回值的综合运用

calculateTip 的作业要求是:billAmount 必填、tipPercentage 可选且默认 15、计算并返回小费金额。注意「返回」二字——它不能像 greetPerson 那样只打印。实现上需要把百分比换算为小数(tipPercentage / 100),这是任务隐含的算术细节;calculateTip(50) 应得到 7.5,与 Part 5 测试预期一致。

五、评分细则(Rubric)解读:五项考核标准逐条对照

作业文档附带的评分表完整如下,这里逐条补充「什么样算 Exemplary」的判据:

考核项 Exemplary(优秀) Adequate(合格) Needs Improvement(需改进)
函数创建 6 个函数全部正确实现,语法与命名规范 4–5 个正确,少量语法问题 ≤3 个或存在严重语法错误
参数与默认值 必填参数、可选参数、默认值均按要求正确使用 参数使用正确但默认值处理有瑕疵 参数实现错误或缺失
返回值 应返回的函数正确返回值,不应返回的函数只做动作 大部分返回值正确,有小问题 return 语句存在明显问题
代码质量 整洁、组织良好、变量名有意义、缩进规范 能运行但可读性/组织性一般 难以阅读或结构混乱
测试 所有函数都有测试调用且结果清晰展示 大部分函数测试充分 测试缺失或不正确

对照自查清单:

  • 函数创建:6 个函数一个不少;命名沿用作业指定的 sayHellogreetPerson 等 camelCase 名称,不要自造同义别名;
  • 参数与默认值greetPerson 的第二参默认 "Hello"calculateTip 的第二参默认 15,且两者都能被显式实参覆盖;
  • 返回值:三个「返回型」函数必须用 return 交出值(否则 sumfullNametip 全是 undefined);三个「动作型」函数不要return(如 return console.log(...) 会返回 undefined,属于多余且暴露对契约的误解);
  • 代码质量:参考第三节的排版——分部分注释、参数命名与作业要求一致、统一缩进;
  • 测试:直接沿用 Part 5 的示例调用即可覆盖全部 6 个函数,并额外验证了 greetPerson 的两种调用形态与 calculateTip 的默认值路径。

六、Bonus Challenges 参考答案

作业末尾提供了三个选做挑战(原样继承自 assignment.md):1)为其中一个函数写箭头函数版本;2)创建一个接收函数作为参数的函数(类似课程中 setTimeout 的例子);3)为函数添加输入校验,优雅处理非法输入。对应参考实现如下,可追加到 functions-practice.js 末尾:

// Bonus 1: addNumbers 的箭头函数版本
// 单表达式箭头函数可省略花括号与 return(隐式返回)
const addNumbersArrow = (num1, num2) => num1 + num2;
console.log(addNumbersArrow(5, 3)); // 8

// Bonus 2: 高阶函数——接收「函数」作为参数(课程文档 setTimeout 同款模式)
// applyTwice 把一个函数 fn 应用两次:fn(fn(value))
function applyTwice(fn, value) {
  return fn(fn(value));
}
const double = (x) => x * 2;
console.log(applyTwice(double, 3)); // 12

// Bonus 3: 输入校验——对非法输入抛出明确错误
function addNumbersSafe(num1, num2) {
  const invalid =
    typeof num1 !== "number" ||
    typeof num2 !== "number" ||
    Number.isNaN(num1) ||
    Number.isNaN(num2);
  if (invalid) {
    throw new TypeError("Both arguments must be valid numbers");
  }
  return num1 + num2;
}

console.log(addNumbersSafe(2, 3));      // 5
// addNumbersSafe("2", 3);              // 抛出 TypeError

三个 Bonus 分别对应课程文档「Functions as parameters for functions」「Fat arrow functions」两个小节:setTimeout(displayDone, 3000) 传递的是函数引用(注意不带括号,带了括号会立即执行并传回返回值),applyTwice 是同一模式的纯函数版本;箭头函数则与课程中 setTimeout(() => {...}, 3000) 的写法完全同构,可用于简短回调场景。

七、佐证:本仓库真实项目代码中的函数写法

为了说明这套函数技能在课程后续项目中的实际用途,仓库里已带答案的项目代码给出了两个现成的观察样本:

  • 打字游戏答案 index.js 通篇采用箭头函数:如 const getRandomQuote = () => quotes[Math.floor(Math.random() * quotes.length)](无参 + 隐式返回),renderQuote 接收一个参数 quote 并操作 DOM,messages.success = (seconds) => \...`` 则是一个带参数并返回字符串的箭头函数——正是作业 Part 3「返回模板字符串」模式的工程化放大版。
  • 太空游戏答案 app.js 顶部用 IIFE(立即执行函数表达式)(() => { ... }) 包裹全部逻辑,并定义了带默认参数的选择器工具 const $ = (sel, ctx = document) => ctx.querySelector(sel)——ctx = document 就是一个默认参数,与作业 Part 2 的 greeting = "Hello" 写法如出一辙。

从源码结构看,这两处代码印证了课程文档的选型建议:可复用的工具函数($getRandomQuote)用命名函数承载、只做一次或简短的回调(事件处理、map 里的映射)用箭头函数承载。

八、验证清单:提交前逐条确认

按作业要求与 Rubric,提交前建议对照以下清单自查(每一项都可由第三节给出的预期输出直接验证):

  1. 文件名为 functions-practice.js,6 个函数名与作业指定完全一致;
  2. 浏览器控制台(F12)或 node functions-practice.js 的运行输出与第三节的预期输出逐行一致,尤其是 Tip for $50 bill: $7.5(验证默认值 15 生效);
  3. greetPerson("Alex")greetPerson("Maria", "Hi") 的输出差异正确体现默认值覆盖逻辑;
  4. sumfullNametip 三个变量拿到的都是真实值而非 undefined(可用 console.log(sum) 单独抽查);
  5. 三个动作型函数(sayHellointroduceYourselfgreetPerson)函数体内无 return
  6. 命名采用 camelCasing,缩进统一,每个部分有清晰的分区注释;
  7. (选做)三个 Bonus 挑战代码追加后不影响原有测试输出。

完成以上步骤后,本作业即覆盖了 2-js-basics/2-functions-methods 一课中函数声明、参数、默认值、返回值、函数作参数、箭头函数等全部核心语法点,可直接作为进入第 3 课「Making Decisions」前的能力自测。

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

项目优选

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