首页
/ JavaScript 函数练习作业精讲:6 个函数吃透参数、默认值与返回值(Web-Dev-For-Beginners 课程指南)

JavaScript 函数练习作业精讲:6 个函数吃透参数、默认值与返回值(Web-Dev-For-Beginners 课程指南)

2026-09-08 09:33:50作者:蔡丛锟

导读

Fun with Functions(函数乐趣多)是 Web-Dev-For-Beginners 课程第 2 单元《JavaScript 基础》第 2 课《方法与函数》的配套实战作业,用于把课上讲过的函数声明、参数与实参、默认参数、return 返回值、模板字面量与 console.log() 输出等知识落到手写代码上。读完本指南,你将不仅能独立完成该作业的全部 5 个部分与 3 个加分挑战,还能对照本仓库中真实游戏与银行应用源码,理解默认参数、箭头函数和高阶函数在工业级 JavaScript 中是如何被实际调用的。

本指南对应的作业原文位于 作业(捷克语译文)(英语原版见 assignment.md),配套讲义见 方法与函数课程 README

JavaScript 函数速写笔记,概览函数、参数与调用等核心概念

作业背景:它处在课程体系的什么位置

在 Web-Dev-For-Beginners 课程的 JavaScript 基础单元(2-js-basics)中,函数是承接"数据类型"、衔接"条件判断"与"数组循环"的核心关卡。第 2 课讲义开篇就把函数类比为福特流水线上的标准化零件:一旦你造出一个可靠的组件,就无需重复从零拼装。课程认为,与其在程序中 20 处复制粘贴同一段逻辑,不如封装一次、按需调用——这正是本作业想让你内化的心智模型。

本作业的定位是课后独立完成的手写编程任务:不要求搭建页面、不要求提交到 GitHub,只需要新建一个 .js 文件、逐条实现函数并用 console.log() 观察输出。作业评分表(Rubric)从"函数创建、参数与默认值、返回值、代码质量、测试"五个维度给出评价标准,既检验语法正确性,也检验命名与缩进等代码卫生习惯。

作业要求总览

创建一个名为 functions-practice.js 的 JavaScript 文件,实现以下 6 个函数,共分 5 个部分:

部分 函数 参数 行为
Part 1 基础函数 sayHello 向控制台输出 "Hello!"
Part 1 基础函数 introduceYourself name 输出形如 "Ahoj, jmenuji se [name]" 的消息
Part 2 默认参数 greetPerson name(必填)、greeting(可选,默认 "Hello" 输出形如 "[greeting], [name]!" 的消息
Part 3 返回值 addNumbers num1num2 返回两数之和
Part 3 返回值 createFullName firstNamelastName 返回拼接好的完整姓名字符串
Part 4 综合运用 calculateTip billAmount(必填)、tipPercentage(可选,默认 15 计算并返回小费金额

💡 提示(原文原话):完成代码后别忘了按 F12 打开浏览器的开发者控制台,才能看到 console.log() 的输出结果。

由于作业文件是纯 JavaScript,你既可以把文件引入一个 HTML 页面在浏览器控制台查看结果,也可以用 Node.js 直接执行(例如 node functions-practice.js)。下文给出每个部分的可行实现与输出解读。

Part 1:基础函数——无参函数与单参函数

第一个函数 sayHello 不带任何参数,唯一职责是在控制台打印问候语。它的语法结构完整展现了函数声明的四要素:function 关键字、函数名、形参括号 ()(此处为空)与函数体花括号 {}

// 1. 基础函数:无参数
function sayHello() {
  console.log("Hello!");
}

第二个函数 introduceYourself 引入第一个参数 name。调用者传入什么值,name 形参就被替换成什么值——这是课程讲义中"参数即占位符"概念的第一次落地。讲义推荐使用模板字面量(反引号 `${})来插值字符串:

// 2. 基础函数:带 name 参数
function introduceYourself(name) {
  console.log(`Ahoj, jmenuji se ${name}`);
}

值得注意的两点(均源自讲义):

  • console.log() 本质是挂在 console 对象上的方法,而这里定义的 sayHello 是独立存在的函数;作业刻意从方法调用起步,让你体会"函数属于对象、函数独立存在"的差别。
  • 调用函数必须带括号:写 sayHello(无括号)只是引用函数本身,不会执行它。

Part 2:默认参数——让函数更灵活的占位符

第三个函数 greetPerson 是作业第一次要求区分"必填参数"与"可选参数"。语法上用等号给形参赋默认值,就像给变量赋初值一样:

// 3. 默认参数:greeting 可选,默认 "Hello"
function greetPerson(name, greeting = "Hello") {
  console.log(`${greeting}, ${name}!`);
}

这里 name 仍然必填,而 greeting 在调用者没有提供时回退到 "Hello"。同一个函数因此支持两种调用姿势:

greetPerson("Alex");            // 未传 greeting → 输出 "Hello, Alex!"
greetPerson("Maria", "Hi");     // 传入 greeting  → 输出 "Hi, Maria!"

讲义用一张状态图解释了无参、带参、带默认值三种函数形态的演进逻辑:从"输出永远相同"到"随输入变化",再到"可选自定义",默认参数是最灵活且向后兼容的做法——新用户可以靠合理默认值快速上手,高级用户仍可自定义。作业第 4 部分 calculateTip 会复用这一机制,可见它正是本课的核心考点。

Part 3:返回值——从"打印"到"交回结果"

前面两个函数都只向控制台打印,本部分则要求函数把计算结果交还给调用者,由调用者决定怎么用。这是讲义强调的"关键洞察":能返回值的函数更通用,因为使用结果的决策权在调用方

第四个函数 addNumbers 返回两个数字之和:

// 4. 返回值:求和
function addNumbers(num1, num2) {
  return num1 + num2;
}

第五个函数 createFullName 用模板字面量拼接姓名并返回单个字符串:

// 5. 返回值:拼接全名
function createFullName(firstName, lastName) {
  return `${firstName} ${lastName}`;
}

理解 return 要抓住两个行为特征(讲义中均有对应陈述):

  1. 一旦执行到 return,函数立即终止,后续代码不再运行;
  2. return 之后的值可以存储进变量、参与表达式运算、或作为参数传入另一个函数。

反过来,如果函数没有 return(例如 Part 1、Part 2 的两个函数),它只是"执行动作",调用结果实质上是 undefined——这就是评分表"返回值"一栏强调"该返回的要返回、不该返回的只做动作"的原因。

Part 4:综合运用——把默认参数与返回值组合起来

第六个函数 calculateTip 把前几部分的能力串成一道真实场景题:账单金额必填、小费比例可选且默认 15(百分比)。注意这里默认值是数值 15 而非字符串,计算时要先换算成比例:

// 6. 综合运用:计算小费
function calculateTip(billAmount, tipPercentage = 15) {
  return billAmount * (tipPercentage / 100);
}

若调用 calculateTip(50),因为未提供第二个实参,tipPercentage 使用默认值 15,返回 50 * 0.15 = 7.5;而 calculateTip(100, 20) 则会返回 20。本部分同时检验三件事:必填/可选参数的正确声明、默认值的合理选取、以及"返回值交给调用方格式化输出"的理念。若想让结果更精确,还可使用 toFixed(2) 保留两位小数(属于加分项级别的自我打磨)。

Part 5:调用测试——用 console.log 验证每个函数

作业要求为每个函数添加调用并借助 console.log() 展示结果。作业原文给出了标准的测试骨架:

// 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}`);

对应预期输出:

调用 预期输出
sayHello() Hello!
introduceYourself("Sarah") Ahoj, jmenuji se Sarah
greetPerson("Alex") Hello, Alex!
greetPerson("Maria", "Hi") Hi, Maria!
addNumbers(5, 3) 返回 8,打印 The sum is: 8
createFullName("John", "Doe") 返回 John Doe,打印 Full name: John Doe
calculateTip(50) 返回 7.5,打印 Tip for $50 bill: $7.5

请格外留意第 3、4 组调用:greetPerson("Alex") 没有第二个实参、命中了默认值;greetPerson("Maria", "Hi") 覆盖了默认值。第 7 组 calculateTip(50) 同理——它们就是在用"同一个函数两种调用"来验证默认参数是否生效。凡是"打印类"函数(sayHello 等)直接调用即可,凡是"返回类"函数(addNumbers 等)则应先存入变量再打印,否则返回值会被白白丢弃。

作业评分标准(Rubric)逐条对照

作业附带的评分表是自查清单,翻译整理如下,建议提交前逐条核对:

维度 优秀(Exemplary) 合格(Adequate) 需改进(Needs Improvement)
函数创建 6 个函数全部正确实现,语法与命名规范 4–5 个函数正确,存在少量语法小错 只实现 3 个及以下,或存在严重语法错误
参数与默认值 按要求正确使用必填参数、可选参数与默认值 参数使用正确,但默认值可能存在瑕疵 参数实现错误或缺失
返回值 该返回值的函数正确返回,不该返回值的只执行动作 大部分返回值正确,有小问题 返回值逻辑存在严重问题
代码质量 代码干净、组织良好,变量命名有意义,缩进正确 代码可运行,但不够整洁或组织不佳 代码难以阅读或结构混乱
测试 所有函数都用合适的调用测试,结果清晰展示 大部分函数得到充分测试 测试不足或调用方式不正确

对照"代码质量"一栏可以反推本课提倡的风格:用有意义的驼峰命名(如 calculateTip 而非 calculate_tip)、每个函数只专注做一件事、保持统一的缩进——这些在 课程讲义"函数最佳实践" 中均有明确表述。

加分挑战详解:箭头函数、高阶函数与输入校验

作业在主干之外给出三个可选的自我挑战,恰好覆盖现代 JavaScript 的进阶语法。

挑战 1:把某个函数改写成箭头函数

箭头函数省去 function 关键字,用 => 连接参数与函数体,是现代 JavaScript 代码库中最常见的写法:

// 传统写法
function addNumbers(num1, num2) {
  return num1 + num2;
}

// 箭头函数写法(单表达式可省略 return 与花括号)
const addNumbers = (num1, num2) => num1 + num2;

挑战 2:让函数接收另一个函数作为参数

讲义以内置的 setTimeout 为例说明了"函数作为参数"(高阶函数)的用法——传参时写函数名而不带括号,等于把函数"托管"出去,由接收方在适当时机回调:

// 讲义中的 setTimeout 示例(毫秒计时)
function displayDone() {
  console.log("3 seconds has elapsed");
}
setTimeout(displayDone, 3000);

// 同样效果也可用匿名函数 / 箭头函数内联:
setTimeout(() => {
  console.log("3 seconds has elapsed");
}, 3000);

更贴近作业的自定义高阶函数可以是:

function applyTwice(func, value) {
  return func(func(value));
}
console.log(applyTwice((n) => n + 1, 5)); // 输出 7

挑战 3:为函数添加输入校验

让函数对非法输入作出优雅处理,例如校验参数确实是数字:

function addNumbers(num1, num2) {
  if (typeof num1 !== "number" || typeof num2 !== "number") {
    console.error("Both arguments must be numbers.");
    return NaN;
  }
  return num1 + num2;
}

在真实仓库中的印证:这些写法不是"纸上谈兵"

上述默认参数、箭头函数与高阶函数在本仓库的真实源码中随处可见,可作为学以致用的参照:

  • 在太空射击游戏 6-space-game/solution/app.js 中,DOM 查询工具函数用箭头函数 + 默认参数实现:const $ = (sel, ctx = document) => ctx.querySelector(sel);——默认值 document 让调用者在绝大多数场景下只需传选择器;同一文件内的事件监听回调大量使用箭头函数与匿名函数,如 img.onload / img.onerror 回调
  • 在银行应用 7-bank-project/solution/app.js 中,查找用户的 find 回调即箭头函数 acc => acc.user === user,异步流程则用 new Promise(resolve => {...}) 把函数作为参数传入——正是挑战 2 所述"回调/高阶函数"思想的工程化放大。

结语与延伸阅读

完成本作业后,你应当已经亲手验证了本课的全部核心概念:函数声明与调用、形参与实参、默认参数的回退行为、return 的立即终止与返回值复用,以及"打印输出"与"返回值"两种函数风格的差别。建议提交前对照 英文原版作业评分表逐项自查,再用加分挑战把箭头函数、高阶函数与输入校验加入你的工具箱。

想继续深挖,可以在本仓库中做两件事:一是通读 第 2 课完整讲义 中关于匿名函数、函数组合与"何时选用哪种语法"的决策矩阵;二是直接阅读 6-space-game/solution/app.js7-bank-project/solution/app.js 这两个真实项目源码,观察函数式写法如何在数百行代码中支撑起完整应用。之后的 条件判断数组与循环 课程还会大量复用你在此处练就的函数能力。

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

项目优选

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