主题
案例-字符串拼接与案例-阶梯水价(Day4 1/3)
本页对应 Day04_JavaScript,共 7 段视频,约 1 小时 1 分。
学习目标
- 能根据给定代码判断
if、switch case及嵌套分支的执行流程和最终变量值,并说明break缺失时的影响。 - 能使用
+完成字符串与变量拼接,正确区分变量写在引号内外,并输出指定格式的个人信息。 - 能使用
if-else if-else编写阶梯水价程序,按 220、300 分档计算费用,并使用isNaN校验用户输入。 - 能推导并写出闰年判断表达式,综合
%4、%100、%400和逻辑运算符,对指定年份输出闰年或平年。 - 能使用
while循环定义循环变量、循环条件和更新表达式,完成指定次数、指定范围、倒序及偶数输出,并避免死循环。 - 能在
while循环中正确初始化累加变量和累乘变量,完成 100 以内数字求和、10 以内奇数求积,并说明循环结束后循环变量的值。
知识点
本节说明与分支回顾
本节笔记未显示图片,故不插入图片;转写稿中的代码按原意整理保留。先纠正同音字:where 应为 while,Lif 应为 else if,不瑞应为 break,艾斯应为 else,实纪年应为世纪年,南本应为 number。
分支结构要掌握:单分支、双分支、多分支(else if 与 switch case)、嵌套。为什么需要:不同场景选择不同结构。怎么想:判等优先 switch case,范围或复杂条件用 else if;case 下要缩进,必要时写 break。易错点:漏 break 会穿透;条件表达式结果要按 true/false 判断。
练习一:
js
let a = 10;
if (110 && 'hello' * 1) {
a++;
}
console.log(a); // 10推导:'hello' * 1 得 NaN,逻辑与第二边不成立,整体不成立,a++ 不执行,所以仍是 10。易错点:不要被左边 110 迷惑,逻辑与要求两边都成立。
练习二:
js
let a = 20;
switch (a) {
case 10: a += 10;
case 20: a += 20;
case 30: a += 30;
case 40: a += 100;
}
console.log(a); // 170从 case 20 进入,未写 break,继续执行 +20、+30、+100,即 20+20+30+100=170。易错点:switch 的“穿透”是调试重点。
字符串拼接案例
为什么需要:开发中经常把变量嵌入提示文本。怎么想:先写完整大字符串,把要替换的位置留标记,再逐段用 + 拼变量。怎么做:
js
let name = '高晓乐';
let gender = '男';
let hometown = '山西';
let hobby = '吃醋';
let money = 0.25;
let message = '我的名字叫' + name + ',性别' + gender +
',我来自' + hometown + ',我的爱好是' + hobby +
',期望薪资是' + money + 'K';
console.log(message);易错点:变量名必须写在引号外;拼接符两边空格可加可不加,变量多时要注意引号闭合。转写中“0.25K”可写成 .25K,但建议保留 0 提高可读性。
阶梯水价案例
为什么需要:分段计费不能简单“总用量乘单价”。怎么想:先判断档位,再分段累加。怎么做:
js
let vol = +prompt('请输入您的用水量(立方米)');
let total;
if (vol <= 220) {
total = 4.05 * vol;
} else if (vol <= 300) {
total = 220 * 4.05 + (vol - 220) * 5.8;
} else {
total = 220 * 4.05 + 80 * 5.8 + (vol - 300) * 8.79;
}
alert('您需要缴纳水费:' + total);推导:进入 else if (vol <= 300) 时,已经隐含 vol > 220,所以超出部分用 vol - 220。易错点:忘记把输入转数字;忽略分段;金额可能出现小数精度问题,输出时可考虑保留两位。也可用 isNaN 先校验输入。
闰年判断案例
为什么需要:闰年规则不是简单“能被 4 整除”。怎么想:先分世纪年与非世纪年。非世纪年:不能被 100 整除且能被 4 整除;世纪年:能被 400 整除。怎么做:
js
let year = +prompt('请输入年份');
if ((year % 100 !== 0 && year % 4 === 0) || year % 400 === 0) {
console.log(year + '是闰年');
} else {
console.log(year + '是平年');
}推导:year % 100 !== 0 排除世纪年,year % 4 === 0 判非世纪年闰年;year % 400 === 0 判世纪年闰年,二者用 || 合并。易错点:漏掉“不能被 100 整除”,会把 1900 误判为闰年;括号虽不改变优先级,但能提高可读性。
while 循环基础与调试
为什么需要:重复执行同一组语句。怎么想:循环条件不能永远成立,循环变量要逐渐趋向不成立。怎么做:
js
let number = 0;
while (number < 10) {
console.log('高晓乐第' + number + '天吃了' + number + '个韭菜馅的包子');
number++;
}
console.log(number); // 10调试:若写 while (true) 会死循环;忘记 number++ 也会死循环。循环结束后 number 是让条件不成立的值,所以是 10。易错点:自增要放在循环体内;输出 0 到 9 共 10 次。
while 循环练习
输出 7 到 15:
js
let i = 7;
while (i <= 15) {
console.log(i);
i++;
}
console.log(i); // 16倒序输出 56 到 43:
js
let i = 56;
while (i >= 43) {
console.log(i);
i--;
}
console.log(i); // 42易错点:倒序要递减;结束值定格在让条件不成立的位置。
输出 10 以内偶数,两种写法:
js
let i = 0;
while (i <= 10) {
if (i % 2 === 0) console.log(i);
i++;
}js
let i = 0;
while (i <= 10) {
console.log(i);
i += 2;
}第二种结束后 i 为 12。易错点:i += 2 不能写成 i++;0 是偶数。
100 以内数字和:
js
let sum = 0;
let i = 1;
while (i <= 100) {
sum += i;
i++;
}
console.log(sum); // 505010 以内奇数乘积:
js
let res = 1;
let i = 1;
while (i < 10) {
res *= i;
i += 2;
}
console.log(res); // 945易错点:求和初始值用 0,求乘积初始值用 1;忘记 i++ 或 i += 2 会死循环。
回顾清单与学习目标
本节是对分支结构的阶段回顾,重点不是新增语法,而是把几种写法放回具体场景里:什么时候用 if,什么时候用 if...else,什么时候用 else if,什么时候用 switch case,以及大括号里还能不能继续嵌套。先保留本节笔记中的清单:
text
1. 单向分支
2. 双向分支
3. 多向分支 else if
4. 多向分支 switch case
5. 嵌套为什么需要回顾:分支结构语法不难,但真实题目里“条件有没有成立”“该进哪个分支”“要不要 break”最容易出错。怎么想:先判断需求是“做不做”“二选一”“多区间判断”还是“等值判断”。怎么做:按清单逐个对照。易错点:不要把 else if 和 switch case 当成互相替代;也不要以为写了分支就一定会执行。
单向分支
为什么需要:有些逻辑只在条件成立时做一件事,不成立就什么也不做,这时用单向 if 最直接。怎么想:先问“条件不成立时要不要有替代动作?”如果不需要,就只写 if。怎么做:写条件表达式,条件成立执行大括号里的语句;不成立就跳过。转写稿中的第一道回顾题就考这个点:代码里有一个单向分支,后面输出变量值。反复强调“核心在于这条语句有没有执行”,因为只有条件成立,变量才会自增 1;条件不成立,变量保持原值。现场推导时,条件表达式虽然带逻辑与,看起来复杂,但最终不成立,所以自增语句没有执行,答案仍是 10。易错点:看到 if 就以为一定会进去;忽略复杂条件最终为假;把“输出变量”误当成“变量一定被改过”。
双向分支
为什么需要:当条件成立做 A,不成立做 B,就需要 if...else。怎么想:把需求翻译成“要么……要么……”,两条路必走一条。怎么做:if 后写成立时的语句,else 后写不成立时的语句。易错点:else 后面不要再写条件;两个分支只会执行一个;大括号内语句要缩进,方便看出归属。转写稿中用“区别能想到吧”提醒:单向分支可能一次都不执行,双向分支在二选一场景中必定进入其中一个分支。
多向分支:else if
为什么需要:当条件不止两个,而且可能是区间判断、复合条件判断时,else if 更合适。怎么想:从上到下依次判断,一旦某个条件成立,就执行对应分支,后面的 else if 不再判断。怎么做:先写第一个 if,再写多个 else if,最后可用 else 兜底。易错点:条件顺序会影响结果;能进入后面的 else if,往往说明前面的条件已经不成立。转写稿提到 else if “各种场景是不是都合适”,而 switch case 更适合判等;所以复杂条件、区间判断优先考虑 else if。
多向分支:switch case
为什么需要:当需求是“表达式等于某个值就做什么,等于另一个值就做什么”,switch case 更清晰。怎么想:先看是不是等值判断;是等值判断就优先 switch case,它搞不定的复杂条件再用 else if。怎么做:用表达式匹配 case,每个 case 后写执行语句,必要时写 break。转写稿第二道题:变量 A 的初值是 20,从 case 20 进入;但每个 case 后没有写 break,所以不会停,会继续往下贯穿执行,先加 20,再加 30,再加 100,即 20 + 20 + 30 + 100 = 170。易错点:漏写 break 会“贯穿”;case 下要注意缩进;switch case 适合判等,不要硬拿它处理复杂区间。
嵌套
为什么需要:真实逻辑常常是“分支里还有分支”。怎么想:先判断外层大条件,再在某个分支内部继续判断小条件。怎么做:if...else 的大括号中可以再套一层 if 或 else if;switch case 的 case 下面也可以继续写逻辑。转写稿强调“大括号中是不是可以再套一层”,甚至 switch case 的 case 下面也可以再套,但 case 下面一定要注意缩进。易错点:嵌套层级太多会降低可读性;缩进混乱会导致自己看错归属;不要为了嵌套而嵌套,能平铺的条件可优先平铺。
小结
本节回顾的关键是“按场景选结构”:单向 if 管“做不做”,if...else 管“二选一”,else if 管多条件,switch case 管等值匹配,嵌套用于分支里再分支。转写稿里两道题分别提醒了两个高频错误:条件不成立时语句不会执行,所以变量可能保持原值;switch case 漏写 break 会继续往下执行。分支语法记得少,但练习要多,重点是把条件、执行路径和变量变化一步步推清楚。
课堂画面






代码示例
示例一:字符串拼接(“+”连接符练习)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>字符串拼接</title>
</head>
<body>
<script>
// 1. 先定义好 5 个变量
var name = '高晓乐'; // 姓名
var gender = '男'; // 性别
var hometown = '山西'; // 家乡
var hobby = '吃醋'; // 爱好
var money = .25; // 期望薪资,单位 K(0.25 的 0 可以省略)
// 2. 思路:先写出完整的大字符串,需要拼变量的地方先用 X 占位,
// 再把 X 删掉,换成 引号结束 + 变量 + 引号开始
var message = '我的名字叫' + name
+ ',性别' + gender
+ ',我来自' + hometown
+ ',我的业余爱好是' + hobby
+ ',我的期望薪资是' + money + 'K';
// 3. 输出看看结果
console.log(message);
</script>
</body>
</html>要点解释:
'...' + name + '...':拼接时变量名必须写在引号外面,写进引号里就变成普通文字了(转写稿原话:“写引号里边就完犊子了”)。- 加号两边的空格加不加都行,语法上没区别,加空格只是为了好看、好读。
money = .25:JS 里0.25的小数点前的 0 可以省略。- 拼接变量多时,建议先写完整字符串、再用“X”占位逐个替换,比边写边拼更不容易出错。
示例二:阶梯水价(多向分支 else if)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>阶梯水价</title>
</head>
<body>
<script>
// 1. 获取用户输入(prompt 得到的是字符串)
var val = prompt('请输入您的用水量(单位:立方米)');
// 2. 先判断用户输入格式对不对,不是数字就提示
if (isNaN(val)) {
alert('请输入正确的格式,必须是数字!');
} else {
// 3. 转成数字再参与计算
val = parseFloat(val);
var total; // 记录总价
if (val <= 220) {
// 第一档:全部按 4.05 算
total = 4.05 * val;
} else if (val <= 300) {
// 第二档:220 的部分按 4.05,超出 220 的部分按 5.8
total = 220 * 4.05 + (val - 220) * 5.8;
} else {
// 第三档:220 部分 + 220~300 这 80 的部分 + 300 以上的部分
total = 220 * 4.05 + 80 * 5.8 + (val - 300) * 8.79;
}
alert('您需要缴纳的水费是:' + total);
}
</script>
</body>
</html>要点解释:
else if (val <= 300)里不用再判断“大于 220”:能走到这一行,说明前面的val <= 220已经不成立了,天然就是大于 220 的。- 三个分支互斥,一次只会执行一个,所以
total不会被重复赋值。 isNaN(val)为true说明输入的不是数字(比如输入hello),要先拦掉;把后续判断放进else里,代码更严谨。- 小数相乘出现很长的小数位是正常现象(浮点精度问题),做金额输出时一般保留两位。
- 阶梯计算套路:每档只算超出部分,
220 * 4.05 + (val - 220) * 5.8,不要整段乘高价。
示例三:while 循环三个练习(偶数 / 求和 / 求积)
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>while 循环</title>
</head>
<body>
<script>
// 需求 1:输出 10 以内所有偶数(含 0 和 10)
var i = 0;
while (i <= 10) {
console.log(i); // 0 2 4 6 8 10
i += 2; // 每次加 2,让条件逐渐趋向不成立
}
console.log('循环结束后 i = ' + i); // 12
// 需求 2:计算 100 以内所有数字的和(含 100)
var sum = 0; // 求和的初始值写 0
var j = 1;
while (j <= 100) {
sum += j; // 相当于 sum = sum + j
j++; // 千万别忘,忘了就是死循环
}
console.log('1~100 的和 = ' + sum); // 5050
console.log('循环结束后 j = ' + j); // 101
// 需求 3:计算 10 以内所有奇数的乘积(1*3*5*7*9)
var result = 1; // 求积的初始值必须是 1,写 0 就永远是 0
var k = 1;
while (k < 10) {
result *= k; // 相当于 result = result * k
k += 2; // 每次加 2,正好跳过偶数
}
console.log('10 以内奇数的乘积 = ' + result); // 945
console.log('循环结束后 k = ' + k); // 11
</script>
</body>
</html>要点解释:
- 一个“正儿八经的循环”必须满足两点:循环条件不能永远成立,且每循环一次条件要越来越趋向不成立(转写稿里
while (true)直接演示了浏览器死机)。 - 循环变量的自增(
i++、i += 2)要写在循环体里面、循环体外面都行但不能漏;写while (i <= 10)却忘了i++,就是典型死循环。 - 输出偶数有两种写法:一是
i += 2直接步进(代码更简洁),二是在循环体里套一个if (i % 2 == 0)单项分支,两种都能得到 0 2 4 6 8 10。 - 求和初始值写
0(加它没影响),求积初始值必须写1(乘 0 结果永远是 0)——这是求积最容易踩的坑。 - 循环结束后,循环变量的值定格在“让条件不成立的那个值”:
i是 12、j是 101、k是 11,而不是最后一个执行循环体的值。
常见错误
switch分支“穿透”,结果比预期大很多- 现象:输入 20,进入
case 20后把后面所有分支都执行了一遍,得到 170 之类的结果。 - 原因:每个
case末尾漏写break,匹配成功后不会自动跳出,会继续往下执行。 - 修法:每个
case处理完立即补break;确实要故意穿透时,加注释说明意图,避免被当成 bug。
- 现象:输入 20,进入
while条件永远成立,浏览器卡死- 现象:页面直接卡住,控制台刷屏,只能结束任务。
- 原因:循环条件写成
true,或循环体内忘了让循环变量变化(漏写i++)。 - 修法:循环前先想清楚“什么条件下停”,循环体内必须让条件逐步趋向不成立;调试时先跑小次数。
循环结束后循环变量的值判断错
- 现象:认为
i <= 10结束后i是 10,实际是 11;i += 2输出 0~10 后认为i是 10,实际是 12。 - 原因:忽略“最后一次进入循环体后还会再执行一次自增”,变量定格在“让条件第一次不成立”的那个值。
- 修法:判断结束值一律按“最后一次成立的值 + 一步变化量”推演;需要精确值时在循环外单独记录。
- 现象:认为
字符串拼接把变量写进引号里
- 现象:页面直接输出
我的名字叫name,而不是变量的值。 - 原因:把变量名写在了字符串字面量内部,它只是普通文本。
- 修法:变量必须放在引号外,用
+连接;拼接较多时先写好整句模板,再用“断开引号 + 变量 + 重新开引号”的方式逐段替换。
- 现象:页面直接输出
累加/累乘的初始值给错
- 现象:求和结果总是 0,或求积结果永远是 0。
- 原因:求和变量初始值给了 1,求积变量初始值给了 0。
- 修法:累加初始值用 0,累乘初始值用 1;写之前先问自己“这个初始值参与运算后会不会污染结果”。
阶梯计费只乘当前单价,漏掉分段
- 现象:用水 250 立方米时直接
250 * 5.8,费用明显偏高。 - 原因:把阶梯价当成“整段按最高档计价”,没有分段累加。
- 修法:先算满额档位部分,再算超出部分;写完后用临界值(220、300)各测一次。
- 现象:用水 250 立方米时直接
闰年条件漏掉“世纪年”分支
- 现象:1900、2100 被判成闰年。
- 原因:只写了“能被 4 整除”,没区分整百年份需要被 400 整除。
- 修法:先用
year % 100 === 0判断是否世纪年,再分别套用两套条件;最后用 1900、2000、2024、2100 四个值回归测试。
prompt拿到的是字符串就直接比较/计算- 现象:输入
"100"与数字比较或相加时结果诡异,或用户乱输入导致条件全部不成立。 - 原因:
prompt返回值是字符串,隐式转换不可控。 - 修法:先
Number()转换,再用isNaN()校验格式;非法输入走单独提示分支,不要混进业务计算。
- 现象:输入
练习
分支穿透排查:给出一段
switch代码(多个case无break),先手写推演输出结果,再上机验证;然后补全break,对比两次结果差异,写出“穿透”发生的位置。阶梯水价边界测试:实现阶梯水价后,分别输入 0、220、220.01、300、300.01、1000,记录每档费用明细;再输入
abc、空字符串,验证非法输入是否被拦截。闰年判断回归表:写一个判断闰年的表达式,用 1900、2000、2024、2100、2200、2023 六个数逐一测试,把每个年份的“世纪年/非世纪年”和判断结果列成表格,检查是否全部正确。
循环改错:给出三段有问题的
while代码(死循环、初始值给错、自增写在if内部导致漏加),找出每段的问题并改正,说明“循环变量必须每次都被改变”的理由。一题多解:输出 0~10 内所有偶数,用两种写法实现(循环体内
if判断、循环变量每次+= 2),比较两种写法循环结束后的变量值分别是多少,并说明为什么不同。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 回顾 | 06:37 |
| 2 | 案例-字符串拼接 | 06:02 |
| 3 | 案例-阶梯水价 | 07:52 |
| 4 | 案例-闰年判断 | 12:41 |
| 5 | while循环01 | 11:14 |
| 6 | while循环02 | 02:44 |
| 7 | while循环03 | 14:15 |
小结
- 分支的坑集中在“该跳不跳”和“条件写漏”:
switch记得break,if记得覆盖所有区间和边界。 - 区间判断要养成“先想边界值”的习惯,220、300、整百年份这类临界点必须单独测。
- 循环三要素缺一不可:初始值、终止条件、变量变化;少任何一个都可能变成死循环或零次循环。
- 循环结束后变量的值永远是“让条件第一次不成立的那个值”,不要凭直觉猜。
- 累加初始值 0、累乘初始值 1,这是必须条件反射的常识。
- 字符串拼接时变量一定在引号外,拼接段数多时先写模板再替换,能显著降低出错率。
prompt的返回值默认是字符串,进入计算前先转换、先校验,非法输入走独立分支。- 这类语法点“记得少、练得多”,写完必须跑一遍边界数据,靠肉眼检查代码是最容易漏坑的方式。