主题
1-12函数及应用(一)
本页对应 第一章JavaScript基础,共 7 段视频,约 1 小时 8 分。
学习目标
- 能使用
function关键字声明函数,并通过“函数名()”调用,说明函数不调用不执行、每次调用都会重新执行函数体。 - 能将重复逻辑(如九九乘法表、1~100累加求和)封装为函数,并说明函数复用与
for循环在执行时机上的区别。 - 能编写带形参和
return的函数,调用时传入实参并接收返回值,区分形参与实参,并判断参数个数不匹配时的执行结果。 - 能利用逻辑与、逻辑或的中断规则改写求和函数,使未传参或传入
undefined时返回0,并解释短路执行过程。 - 能为形参设置默认参数,说明默认值生效条件(未传实参或实参为
undefined),并比较默认参数与逻辑中断的适用场景。 - 能封装并调用“秒数转换为时、分、秒”的函数,验证输入秒数后输出正确结果。
知识点
函数是什么:先封装再复用
为什么需要:页面不同位置要多次打印同一段逻辑时,复制代码既啰嗦又难维护。函数把“相同或相似逻辑”包起来,需要时调用一次即可,核心价值是代码复用。
怎么想:函数是可被重复使用的代码块,可以理解成一个“盒子”,把代码封装进去;定义只是准备盒子,调用才真正执行。
怎么做:用 function 声明函数,函数名后加 () 调用。
javascript
function sayHi() {
console.log('嗨~')
}
sayHi()
sayHi()调试时先只写定义,页面不会输出;补上 sayHi() 后才执行,说明“声明不执行,调用才执行”。
易错点:函数名与变量命名一致,采用小驼峰,常用动词;循环写完刷新就执行,函数则要等到调用时才执行,执行时机不同。
完整函数:参数、返回值与整体认知
为什么需要:只写 sum 求固定 10+20 不灵活,结果还在函数内部打印,外部拿不到。完整函数应能接收数据、处理数据、返回结果。
怎么想:像榨汁机:调用者放“原料”(实参),函数用“形参”接收,内部处理后用 return 把结果返回给调用者。
怎么做:
javascript
function sum(x, y) {
return x + y
}
console.log(sum(1, 2)) // 3返回值细节:return 会立即结束函数,后面代码不执行;return 与被返回表达式不要换行;没有 return 时默认返回 undefined。
易错点:return 后写代码不会执行;return 后换行可能被自动补分号;无返回值不要误以为返回 0。
形参和实参:个数不匹配怎么推
为什么需要:函数要灵活,就要把调用时的数据传进去。声明函数时小括号里是形参,调用时小括号里是实参。
怎么想:传参过程类似赋值,sum(1,2) 可理解为 x=1、y=2;形参可当作变量理解。
怎么做:
javascript
function sum(x, y) {
return x + y
}
console.log(sum(1, 2)) // 3
console.log(sum(1)) // NaN
console.log(sum(1, 2, 3)) // 3推导:sum(1) 时 x=1,y 没接到值,默认是 undefined,所以 1 + undefined 得 NaN;实参多余时,多出的会被忽略。
易错点:形参过多自动补 undefined,实参过多多余忽略;开发中提倡实参与形参个数统一;形参可看作局部变量。
逻辑中断与默认参数:让缺参更严谨
为什么需要:sum() 不传参会得到 NaN,但更合理的是返回 0,像查银行卡余额没金额也显示 0。
怎么想:逻辑与 && 左边为假就中断;逻辑或 || 左边为真就中断。可用 x = x || 0 兜底。
怎么做:
javascript
function sum(x, y) {
x = x || 0
y = y || 0
return x + y
}
console.log(sum()) // 0
console.log(sum(1, 2)) // 3默认参数更简单:function sum(x = 0, y = 0) { return x + y }。默认值只在没有实参或实参为 undefined 时生效。
易错点:默认参数主要处理形参;逻辑中断还能处理其他取值场景,二者不是谁替代谁。
作用域与匿名函数:变量边界和函数表达式
为什么需要:变量需要有可用范围,减少命名冲突;匿名函数没有名字,不能直接调用,需要赋值给变量或立即执行。
怎么想:全局作用域作用于整个 script 或独立 js 文件;局部作用域包括函数作用域和块级作用域;访问变量遵循“就近原则”。
怎么做:函数表达式先定义后使用;IIFE 用于避免全局变量污染,多个立即执行函数要用 ; 隔开。
javascript
let fn = function() {
console.log('函数表达式')
}
fn()
(function(){ /* ... */ })();
(function(){ /* ... */ }());易错点:函数内变量未声明直接赋值会变成全局变量,强烈不推荐;形参可看作局部变量;函数表达式必须先定义后使用。
需求与效果:先把“秒数”变成看得懂的时分秒

为什么需要:用户输入的是“总秒数”,但页面要展示的是“小时、分钟、秒”。如果直接把 10000 秒显示出来,阅读成本高;转换成 02:46:40 更直观。转写稿中也明确说,这个案例是在为后面的倒计时效果做铺垫。
怎么想:整个流程分三步:先弹窗拿到总秒数;再把总秒数交给函数计算时、分、秒并补 0;最后把结果拼接成 HTML 输出到页面。
怎么做:用 prompt 获取输入,用 +prompt(...) 转成数字;封装 getTime;用 document.write 输出页面结构。
易错点:prompt 默认返回字符串,虽然参与除法时常会隐式转换,但建议主动用 + 转数字;不要把“补 0 后的字符串”再拿去做数学计算。
计算公式:为什么是 /60/60%24、/60%60、%60
为什么需要:时间换算是 60 进制,不是 10 进制。总秒数要先除以 60 得到分钟,再除以 60 得到小时;余数才是剩下的分钟和秒。
怎么想:以转写稿中的例子“10000 秒”推导:
- 小时:
parseInt(10000 / 60 / 60 % 24)10000/60/60 ≈ 2.777,%24后仍取 2,结果是2。 - 分钟:
parseInt(10000 / 60 % 60)10000/60 ≈ 166.66,166.66 % 60 ≈ 46.66,取整为46。 - 秒数:
parseInt(10000 % 60)10000 % 60 = 40。
所以 10000 秒对应 2 小时 46 分 40 秒,和转写稿演示一致。
怎么做:在函数内分别写 h、m、s 三个变量,用 parseInt 取整。
易错点:小时公式里有 %24,表示按 24 小时循环显示;如果需求是“累计小时”而不是“当天小时”,就不能盲目 %24。本案例按笔记公式保留 %24。
函数封装与补 0:把重复逻辑装进“盒子”
为什么需要:计算和补 0 是一段完整逻辑,封装成函数后结构更清楚,也方便以后复用。转写稿中反复强调:函数是把代码“包裹/封装”起来,定义后不会自动执行,必须调用。
怎么想:先算数字,再补 0,最后返回 HTML 字符串。补 0 的判断是“小于 10 就在前面拼一个 '0'”。
怎么做:
js
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s函数里先 console.log(h, m, s) 调试数值,再 return 三个 <span>。注意笔记代码中形参写了默认值 t = 0,未传参时也有兜底值。
易错点:补 0 后 h/m/s 可能变成字符串,不要再拿它们做加减;返回的是 HTML 字符串,不是数字;模板字符串要用反引号,变量用 ${}。
页面输出与调试:先看控制台,再写页面
为什么需要:如果一上来就拼 HTML,出错时不容易判断是计算错了,还是结构写错了。
怎么想:先验证 getTime(totalSeconds) 返回的字符串是否正确,再把它插入 .timer 容器。
怎么做:笔记中先用 let str = getTime(totalSeconds) 接收返回值,console.log(str) 查看;然后用 document.write 输出完整 .box 结构,把 \${str} 放进 .timer 中。
易错点:document.write 在页面加载阶段执行没问题,但在页面加载完成后调用可能覆盖原文档;本案例是加载时执行,按笔记写法即可。还要注意 HTML 中的类名 hour/minute/second 与 CSS 对应。
完整代码
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>综合案例-转换时间案例</title>
<style>
.box {
position: relative;
width: 190px;
height: 260px;
color: #fff;
background: #e83632 url(./images/bg.png) 50%/contain no-repeat;
}
.title {
width: 100%;
text-align: center;
font-size: 30px;
font-weight: 700;
padding-top: 31px;
}
.count {
margin-top: 90px;
font-size: 14px;
text-align: center;
}
.timer {
margin-left: auto;
margin-right: auto;
width: 130px;
height: 30px;
margin-top: 10px;
display: block;
}
.timer span {
position: relative;
float: left;
width: 30px;
height: 30px;
text-align: center;
background-color: #2f3430;
margin-right: 20px;
color: white;
font-size: 20px;
}
.timer span:nth-child(-n+2)::after {
content: ":";
display: block;
position: absolute;
right: -20px;
font-weight: bolder;
font-size: 18px;
width: 20px;
height: 100%;
top: 0;
}
.timer span:last-child {
margin-right: 0;
}
</style>
</head>
<body>
<!-- <div class="box">
<div class="title">计算时间</div>
<div>
<div class="count">转换为时分秒</div>
<div class="timer">
<span class="hour">01</span>
<span class="minute">22</span>
<span class="second">58</span>
</div>
</div>
</div> -->
<script>
// 转换时分秒案例
// 计算公式:计算时分秒
// 小时: h = parseInt(总秒数 / 60 / 60 % 24)
// 分钟: m = parseInt(总秒数 / 60 % 60)
// 秒数: s = parseInt(总秒数 % 60)
// 1. 用户输入总的秒数
let totalSeconds = +prompt('请您输入总的秒数:')
// 2. 封装函数 getTime,把总的秒数转换为时分秒,注意记得数字补0 哦
function getTime(t = 0) {
// 转换小时
let h = parseInt(t / 60 / 60 % 24)
// 转换分钟
let m = parseInt(t / 60 % 60)
// 转换秒数
let s = parseInt(t % 60)
// 数字补0
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
console.log(h, m, s)
return `
<span class="hour">${h}</span>
<span class="minute">${m}</span>
<span class="second">${s}</span>
`
}
let str = getTime(totalSeconds) // 实参
console.log(str)
// 3. 页面打印输出
document.write(`
<div class="box">
<div class="title">计算时间</div>
<div>
<div class="count">转换为时分秒</div>
<div class="timer">
${str}
</div>
</div>
</div>
`)
</script>
</body>
</html>课件图示








代码示例
示例一:函数声明与调用、参数与返回值
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JavaScript 基础 - 声明和调用</title>
</head>
<body>
<script>
// 函数:是可以被重复使用的代码块,作用是有利于代码复用
// 1. 声明(定义)了最简单的函数,既没有形式参数,也没有返回值
function sayHi() {
console.log('嗨~')
}
// 函数调用,这些函数体内的代码逻辑会被执行
// 函数名()
sayHi()
// 可以重复被调用,多少次都可以
sayHi()
// 2. 完整函数:参数 + 返回值
function sum(x, y) { // x、y 是形参
return x + y
}
console.log(sum(1, 2)) // 3
console.log(sum(1)) // NaN 1 + undefined
console.log(sum(1, 2, 3)) // 3 多余的实参会被忽略
// 3. return 细节:没有 return 默认返回 undefined
function fn() {}
console.log(fn()) // undefined
</script>
</body>
</html>要点:
function声明函数,函数名采用小驼峰、尽量用动词;声明好的函数不会自动执行,必须函数名()调用。- 形参(声明时)本质就是变量,实参(调用时)的值会依次赋给形参;形参多则自动补
undefined,实参多则被忽略,开发中提倡个数统一。 return会立即结束函数,后面的代码不执行;return和被返回的表达式之间不能换行,否则自动补分号等于返回undefined。
示例二:逻辑中断与默认参数
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>逻辑中断与默认参数</title>
</head>
<body>
<script>
// 1. 逻辑与中断:左边为假则中断并返回左边的值;左边为真则返回右边的值
console.log(false && 1 + 2) // false
console.log(0 && 1 + 2) // 0
console.log('' && 1 + 2) // ''
console.log(undefined && 1 + 2) // undefined
console.log(true && 1 + 2) // 3 此处不会发生逻辑中断
console.log(1 && 1 + 2) // 3 此处不会发生逻辑中断
// 2. 逻辑或中断:左边为真则中断并返回左边的值;左边为假则返回右边的值
console.log(true || 1 + 2) // true 发生了中断
console.log(1 || 1 + 2) // 1 发生了中断
console.log(false || 1 + 2) // 3 此处不会发生逻辑中断
// 3. 使用场景一:用逻辑或中断让求和函数更严谨
function sum1(x, y) {
x = x || 0
y = y || 0
return x + y
}
console.log(sum1()) // 0
console.log(sum1(1, 2)) // 3
// 4. 使用场景二:默认参数,写法更简单
function sum2(x = 0, y = 0) {
return x + y
}
console.log(sum2()) // 0
console.log(sum2(undefined, undefined)) // 0
console.log(sum2(1, 2)) // 3
</script>
</body>
</html>要点:
- 逻辑中断(逻辑短路)只存在于
&&和||中;为假的 6 种情况:false、0、''、null、undefined、NaN,其余都为真。 x = x || 0:有实参时左边为真直接中断、原值保留;无实参时左边为undefined(假),取右边的0,从而避免undefined + undefined = NaN。- 默认参数
x = 0只在没有实参传递、或传递的是undefined时才执行;传了具体值就优先用实参。 - 两者区别:处理形参用默认参数更简单;逻辑中断除了参数还能做别的取值兜底(如获取不到值就用 1)。
示例三:综合案例——秒数转换为时分秒
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>综合案例-转换时间案例</title>
<style>
.box {
position: relative;
width: 190px;
height: 260px;
color: #fff;
background: #e83632 url(./images/bg.png) 50%/contain no-repeat;
}
.title {
width: 100%;
text-align: center;
font-size: 30px;
font-weight: 700;
padding-top: 31px;
}
.count {
margin-top: 90px;
font-size: 14px;
text-align: center;
}
.timer {
margin-left: auto;
margin-right: auto;
width: 130px;
height: 30px;
margin-top: 10px;
display: block;
}
.timer span {
position: relative;
float: left;
width: 30px;
height: 30px;
text-align: center;
background-color: #2f3430;
margin-right: 20px;
color: white;
font-size: 20px;
}
.timer span:nth-child(-n+2)::after {
content: ":";
display: block;
position: absolute;
right: -20px;
font-weight: bolder;
font-size: 18px;
width: 20px;
height: 100%;
top: 0;
}
.timer span:last-child {
margin-right: 0;
}
</style>
</head>
<body>
<script>
// 转换时分秒案例
// 计算公式:
// 小时: h = parseInt(总秒数 / 60 / 60 % 24)
// 分钟: m = parseInt(总秒数 / 60 % 60)
// 秒数: s = parseInt(总秒数 % 60)
// 1. 用户输入总的秒数
let totalSeconds = +prompt('请您输入总的秒数:')
// 2. 封装函数 getTime,把总的秒数转换为时分秒,注意记得数字补0 哦
function getTime(t = 0) {
// 转换小时
let h = parseInt(t / 60 / 60 % 24)
// 转换分钟
let m = parseInt(t / 60 % 60)
// 转换秒数
let s = parseInt(t % 60)
// 数字补0
h = h < 10 ? '0' + h : h
m = m < 10 ? '0' + m : m
s = s < 10 ? '0' + s : s
console.log(h, m, s)
return `
<span class="hour">${h}</span>
<span class="minute">${m}</span>
<span class="second">${s}</span>
`
}
let str = getTime(totalSeconds) // 实参
console.log(str)
// 3. 页面打印输出
document.write(`
<div class="box">
<div class="title">计算时间</div>
<div>
<div class="count">转换为时分秒</div>
<div class="timer">
${str}
</div>
</div>
</div>
`)
</script>
</body>
</html>要点:
prompt返回的是字符串,前面加+转成数字,否则/、%运算结果会出错。parseInt取整;小时用% 24保证不超过 24 小时;t = 0是默认参数,防止没有传入秒数时算出NaN。- 补 0 用三元表达式
h < 10 ? '0' + h : h,注意要把结果重新赋值回变量,只写表达式不赋值等于没补。 - 函数内部用
return把拼接好的模板字符串交给调用者,由外部document.write渲染,体现“封装 + 返回值”的配合;.box的背景图./images/bg.png需存在对应图片,缺失不影响结构显示。
常见错误
- 现象:页面没有任何输出,误以为函数写错 → 原因:只声明了函数,没有调用 → 修法:声明后按需写
函数名()调用,并检查调用语句是否执行到。 - 现象:函数明明计算了,外部却拿到
undefined→ 原因:return后换行,或函数根本没有return→ 修法:return与返回表达式写在同一行;需要结果时显式返回。 - 现象:
sum(1)得到NaN,sum(1,2,3)结果与预期不一致 → 原因:形参与实参数量不匹配 → 修法:调用与定义保持数量一致;入口处用默认参数或兜底逻辑处理缺省值。 - 现象:函数表达式在定义前调用直接报错 → 原因:函数表达式本质是赋值,必须先定义后使用 → 修法:先写
let fn = function(){},再调用fn()。 - 现象:连续写多个立即执行函数时报错 → 原因:多个 IIFE 之间缺少分隔 → 修法:每个 IIFE 后补分号,或使用前置分号分隔。
- 现象:函数内部变量跑到全局,造成命名污染 → 原因:变量未声明就直接赋值 → 修法:局部变量显式声明,形参按局部变量使用。
- 现象:传入
0或空字符串时被默认值替换 → 原因:误把逻辑或兜底当成默认参数使用 → 修法:参数缺省优先用默认参数;需要兜底时先确认业务是否允许0、''等假值。
练习
- 封装
getSum(x, y = 0)返回两数之和,分别调用getSum()、getSum(5)、getSum(1, 2),写出结果并说明原因。 - 封装
getTime(totalSeconds = 0),返回HH:MM:SS字符串,要求时分秒不足两位补0,并分别测试不传参、传10000。 - 写出下列输出:
console.log(0 || 5)、console.log(5 || 0)、console.log(0 && 5)、console.log(5 && 0)。 - 用函数表达式封装“求 1 到 n 的累加和”,
n默认100,先定义后调用,分别测试sum(10)和不传参调用。 - 用两个 IIFE 分别输出当前小时和分钟(不足两位补
0),要求连续书写不报错,并避免全局变量污染。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 今日内容 | 01:12 |
| 2 | 函数的基本使用 | 13:55 |
| 3 | 函数封装小练习 | 04:46 |
| 4 | 函数的整体认知 | 12:53 |
| 5 | 函数参数 | 10:01 |
| 6 | 逻辑中断 | 16:11 |
| 7 | 默认参数 | 09:41 |
小结
- 函数的核心价值是封装与复用,声明不等于执行,调用才会执行。
- 完整函数要关注入参、内部处理、返回值三个环节,调用者通过返回值获取结果。
- 参数数量可以不一致,但开发中应尽量统一;默认参数只处理缺省或
undefined。 return会立即结束函数,返回表达式不要换行;没有return时结果为undefined。- 作用域访问遵循就近原则,局部变量应显式声明,避免意外污染全局。
- 匿名函数常用于函数表达式和 IIFE;函数表达式先定义后调用,多个 IIFE 要用分号分隔。
- 逻辑中断适合做取值兜底,但要注意
0、空字符串等合法假值场景。 - 时间转换类案例应先计算、再补零、最后返回,避免在函数内部直接输出而降低复用性。