一、回顾与本篇目标
在上一篇中,你学会了用 JavaScript 操作页面元素:获取元素、修改文字、改变样式、响应点击事件。你已经能做出点击按钮切换内容的小交互了。
但你可能发现了一个问题:如果多个按钮要做类似的事情,代码就得写很多遍,改起来也很麻烦。而且,你只能做“如果 A 就做 B”的简单判断,遇到多种情况就不知道怎么处理了。
这一篇,我们要学两个让代码更强大、更优雅的核心概念:函数和控制流。函数让你把代码打包成可复用的模块,控制流让你能根据不同的条件执行不同的代码。
本篇的目标:
- 理解函数的本质,学会定义带参数的函数
- 掌握
if...else if...else多分支条件判断 - 学会用
prompt()让用户输入数据 - 综合运用所学,做出一个“猜数字”小游戏
二、函数:把代码打包成可复用的模块
为什么需要函数
前面我们写的代码有个问题:每次做类似的事情,都要把相同的代码再写一遍。
// 没有函数:修改三个元素,代码重复
document.getElementById('el1').style.color = 'red';
document.getElementById('el2').style.color = 'red';
document.getElementById('el3').style.color = 'red';
如果有一天要把红色改成蓝色,你得改三个地方。如果有 100 个元素呢?这就是“复制粘贴式编程”的痛点。
函数的本质:把一段代码打包,给它起个名字,以后需要时直接喊它的名字就行。
函数的定义与调用
定义函数(function declaration):
function 函数名() {
// 函数体:要执行的代码
}
调用函数(function call):
函数名();
完整示例:
<script>
// 定义函数
function sayHello() {
console.log('你好!');
console.log('欢迎学习 JavaScript!');
}
// 调用函数(写多少遍就执行多少遍)
sayHello(); // 执行第一次
sayHello(); // 执行第二次
sayHello(); // 执行第三次
</script>
关键理解:
- 定义函数不会立刻执行它。就像你写了一份菜谱,没有真正做菜。
- 调用函数才是真正执行里面的代码。就像你照着菜谱做菜。
- 函数可以被多次调用,每次调用都会执行一遍函数体里的代码。
带参数的函数
上面的 sayHello() 每次输出都一模一样。如果我们想每次输出不同的内容呢?这就需要参数。
参数是函数定义时预留的“空位”,调用时你把具体的值传进去。
function greet(name) { // name 是参数(空位)
console.log('你好,' + name + '!');
}
greet('张三'); // 你好,张三!
greet('李四'); // 你好,李四!
greet('王五'); // 你好,王五!
多参数:
function introduce(name, age, city) {
console.log(name + '今年' + age + '岁,来自' + city + '。');
}
introduce('张三', 28, '上海');
introduce('李四', 22, '北京');
术语:
- 形参(parameter):定义函数时括号里的变量名(
name、age、city),用来占位。 - 实参(argument):调用函数时传入的具体值(
'张三'、28、'上海')。
带返回值的函数
有时候我们不仅希望函数做事情,还希望它能交回一个结果。这就需要 return。
function add(a, b) {
let result = a + b;
return result; // 把结果交回去
}
let sum1 = add(3, 5); // sum1 = 8
let sum2 = add(10, 20); // sum2 = 30
console.log(sum1 + sum2); // 38
return 的两个作用:
- 把函数内部计算的结果传递出去。
- 立即结束函数的执行。return 后面的代码不会运行。
函数实战:用函数改写重复代码
回顾开头的痛点,用函数改写:
// 定义一个函数:把指定元素变成红色
function makeRed(elementId) {
document.getElementById(elementId).style.color = 'red';
}
// 简洁的调用
makeRed('el1');
makeRed('el2');
makeRed('el3');
makeRed('el100'); // 再多的元素也不怕
这就是函数的核心价值:一次定义,重复使用,修改一处,全部生效。
三、条件判断:让代码有选择能力
if...else:二选一
上一篇文章我们已经用了 if...else,现在来深入理解它的语法:
if (条件) {
// 条件成立时执行
} else {
// 条件不成立时执行
}
条件:写在括号里的表达式,结果必须是布尔值 true 或 false。
let score = 85;
if (score >= 60) {
console.log('及格了');
} else {
console.log('不及格');
}
// 输出:及格了
比较运算符
条件判断离不开比较。以下是所有比较运算符:
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
> |
大于 | 10 > 5 |
true |
< |
小于 | 10 < 5 |
false |
>= |
大于等于 | 10 >= 10 |
true |
<= |
小于等于 | 5 <= 3 |
false |
=== |
等于(严格相等) | 10 === 10 |
true |
!== |
不等于 | 10 !== 5 |
true |
重要提醒:判断“等于”用三个等号 ===,不是两个等号 ==。两个等号会做类型转换,可能产生意外的结果。作为初学者,养成用 === 的习惯:
console.log(0 == false); // true(不要用)
console.log(0 === false); // false(推荐)
if...else if...else:多选一
生活中不止两种情况。比如根据分数划分等级:
let score = 85;
if (score >= 90) {
console.log('优秀');
} else if (score >= 80) {
console.log('良好');
} else if (score >= 60) {
console.log('及格');
} else {
console.log('不及格');
}
// 输出:良好
执行逻辑:浏览器从上到下依次检查每个条件。第一个成立的条件对应的代码会被执行,后面的条件不再检查。如果所有条件都不成立,执行 else 里的代码。
注意顺序:如果把条件顺序写反,会导致逻辑错误:
// 错误示范
if (score >= 60) {
console.log('及格');
} else if (score >= 80) {
console.log('良好'); // 永远不会执行!因为 >= 60 已经兜住了
}
原则:条件应该从最严格到最宽松排列,或者从范围最小到范围最大排列。
逻辑运算符:组合多个条件
有时候一个条件不够,需要同时满足多个或满足其一即可。
| 运算符 | 含义 | 示例 | 何时为 true |
|---|---|---|---|
&& |
并且(AND) | age > 18 && age < 60 |
两个条件都成立 |
|| |
或者(OR) | score < 0 || score > 100 |
至少一个条件成立 |
! |
取反(NOT) | !isStudent |
条件不成立时 |
示例:
let age = 25;
let hasTicket = true;
// 并且:两个条件必须同时满足
if (age >= 18 && hasTicket) {
console.log('允许入场');
}
// 或者:满足一个即可
if (age < 18 || age > 60) {
console.log('享受半价优惠');
}
// 取反:把 true 变 false,false 变 true
let isLoggedIn = false;
if (!isLoggedIn) {
console.log('请先登录');
}
四、与用户互动:prompt()
目前为止,我们和用户的互动都是“点击按钮”。有时候我们需要让用户输入信息,比如姓名、密码、数字。
prompt() 会弹出一个输入框,用户可以在里面打字。输入的内容以字符串形式返回。
基本用法
let name = prompt('请输入你的名字:');
console.log('你好,' + name + '!');
浏览器会弹出一个小窗口,等待用户输入。用户点击“确定”,输入的内容就存进变量 name。如果用户点击“取消”,name 的值是 null。
重要:prompt() 的返回值是字符串
即使用户输入数字,prompt() 返回的也是字符串:
let userInput = prompt('请输入一个数字:');
console.log(typeof userInput); // 'string',不是 'number'
console.log(userInput + 10); // '10' + 10 → '1010'(字符串拼接!)
如果要对输入的数字做数学运算,必须先用 Number() 转换:
let userInput = prompt('请输入一个数字:');
let num = Number(userInput); // 把字符串转成数字
console.log(num + 10); // 现在是数学加法了
五、综合实战:猜数字小游戏
下面这个项目综合运用了本篇的所有知识点:函数、条件判断、逻辑运算符、prompt()、操作页面元素。请仔细阅读并手敲运行:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>猜数字游戏</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background: linear-gradient(135deg, #667eea, #764ba2);
font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
}
.game-box {
background: white;
width: 400px;
padding: 40px;
border-radius: 16px;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
text-align: center;
}
.game-box h2 {
color: #333;
margin: 0 0 8px 0;
}
.game-box .subtitle {
color: #999;
font-size: 14px;
margin-bottom: 24px;
}
.game-box .result {
background: #f8f9fa;
padding: 16px;
border-radius: 8px;
margin: 20px 0;
font-size: 14px;
color: #555;
min-height: 20px;
line-height: 1.6;
}
.game-box .remaining {
font-size: 24px;
color: #667eea;
font-weight: bold;
margin: 12px 0;
}
.game-box button {
padding: 12px 32px;
background: #667eea;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
}
.game-box button:hover {
background: #5a6fd6;
}
.game-box button:disabled {
background: #ccc;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="game-box">
<h2>🎯 猜数字游戏</h2>
<p class="subtitle">我心里想了一个 1-100 之间的数,你来猜猜看?</p>
<div class="remaining">剩余次数:<span id="chances">7</span></div>
<div class="result" id="result">
准备好了吗?点击下方按钮开始游戏。
</div>
<button id="guessBtn">开始猜!</button>
</div>
<script>
// ========== 游戏数据 ==========
let secretNumber; // 秘密数字
let remainingChances; // 剩余次数
let gameOver; // 游戏是否结束
// 获取页面元素
let resultEl = document.getElementById('result');
let chancesEl = document.getElementById('chances');
let guessBtn = document.getElementById('guessBtn');
// ========== 函数定义 ==========
// 初始化游戏
function initGame() {
// Math.random() 生成 0-0.999... 的随机小数
// Math.floor() 向下取整
secretNumber = Math.floor(Math.random() * 100) + 1;
remainingChances = 7;
gameOver = false;
chancesEl.textContent = remainingChances;
resultEl.textContent = '新游戏开始!请输入一个 1-100 之间的数字。';
resultEl.style.color = '#555';
guessBtn.textContent = '猜!';
guessBtn.disabled = false;
console.log('【开发调试】秘密数字是:' + secretNumber);
}
// 处理用户猜测
function handleGuess() {
// 游戏已结束,不再处理
if (gameOver) return;
// 弹出输入框
let userInput = prompt('请输入你猜的数字(1-100):');
// 用户点击了取消
if (userInput === null) return;
// 把输入转成数字
let guess = Number(userInput);
// 验证输入是否合法
if (!validateInput(guess)) return;
// 核心判断逻辑
checkAnswer(guess);
}
// 验证输入
function validateInput(guess) {
// isNaN() 检查一个值是不是 NaN(非数字)
if (isNaN(guess)) {
resultEl.textContent = '❌ 请输入一个有效的数字!';
resultEl.style.color = '#e74c3c';
return false;
}
// 检查范围
if (guess < 1 || guess > 100) {
resultEl.textContent = '❌ 数字必须在 1 到 100 之间!';
resultEl.style.color = '#e74c3c';
return false;
}
return true; // 验证通过
}
// 检查答案
function checkAnswer(guess) {
remainingChances--;
chancesEl.textContent = remainingChances;
if (guess === secretNumber) {
// 猜中了!
resultEl.textContent = '🎉 恭喜你!答案就是 ' + secretNumber + '!你用了 ' + (7 - remainingChances) + ' 次猜中。';
resultEl.style.color = '#27ae60';
endGame();
} else if (remainingChances === 0) {
// 次数用完了
resultEl.textContent = '😢 很遗憾,次数用完了。正确答案是 ' + secretNumber + '。';
resultEl.style.color = '#e74c3c';
endGame();
} else if (guess > secretNumber) {
// 猜大了
resultEl.textContent = '📈 太大了!还剩 ' + remainingChances + ' 次机会。';
resultEl.style.color = '#e67e22';
} else {
// 猜小了
resultEl.textContent = '📉 太小了!还剩 ' + remainingChances + ' 次机会。';
resultEl.style.color = '#3498db';
}
}
// 结束游戏
function endGame() {
gameOver = true;
guessBtn.textContent = '再来一局';
}
// ========== 事件绑定 ==========
guessBtn.onclick = function() {
if (gameOver) {
// 游戏结束状态 → 点击开始新游戏
initGame();
} else {
// 游戏进行中 → 点击猜测
handleGuess();
}
};
// ========== 页面加载时自动开始新游戏 ==========
initGame();
</script>
</body>
</html>
逐块解析——这是整个入门系列最复杂的一个例子,请耐心阅读:
- 游戏数据结构:三个全局变量
secretNumber(答案)、remainingChances(剩余次数)、gameOver(是否结束),贯穿整个游戏。 initGame():初始化游戏状态。生成 1-100 的随机整数(Math.random() * 100得到 0-99.99…,Math.floor去掉小数,+1保证范围是 1-100),重置次数和界面。最后用console.log打印答案(这是开发调试的小技巧,正式发布时可以删掉这行)。handleGuess():处理整个猜测流程。先检查游戏是否结束,然后弹出prompt()让用户输入,接着验证输入,最后判断结果。validateInput(guess):带返回值的函数。验证通过返回true,不通过返回false。调用方根据返回值决定是否继续。isNaN()是一个内置函数,用来检查一个值是不是“非数字”(NaN = Not a Number)。checkAnswer(guess):核心判断逻辑。用了完整的if...else if...else链,从最特殊的情况(猜对、次数用完)到一般情况(偏大、偏小)依次判断。每种情况都更新页面上的提示文字和颜色。endGame():设置游戏结束标志,把按钮文字改成“再来一局”。- 按钮的两种模式:同一个按钮,根据
gameOver状态执行不同的操作——这是状态驱动的编程思维。
打开这个页面,玩几局,感受一下自己写的程序。然后试着读代码,找到每个函数被调用的位置,追踪数据的流动。
六、本篇动手练习
练习 1:函数定义与调用练习
新建 practice8-1.html,定义一个名为 greet 的函数,接收一个参数 name,在控制台输出“XXX,早上好!”。然后分别用“张三”、“李四”、“王五”调用三次。
练习 2:带返回值的函数练习
新建 practice8-2.html,定义三个函数:add(a, b) 返回两数之和,subtract(a, b) 返回两数之差,multiply(a, b) 返回两数之积。用三组不同的参数调用它们,把结果输出到控制台。
练习 3:条件判断练习
新建 practice8-3.html,用 prompt() 让用户输入年龄,然后用 if...else if...else 判断:0-12 岁输出“儿童”,13-17 岁输出“青少年”,18-59 岁输出“成年人”,60 岁以上输出“老年人”。注意先把输入转成数字。
练习 4:猜数字游戏改造
打开第五节的综合代码,做以下改造:
- 把最大猜测次数从 7 改为 10。
- 把数字范围从 1-100 改为 1-50(同时修改
prompt提示文字、验证范围、随机数生成逻辑)。 - 增加一个“显示答案”的调试按钮,点击后在控制台输出当前秘密数字。
- 当用户猜错时,除了提示“太大”或“太小”,还显示“你猜的数字是 XX”。
七、本篇小结
这一篇你学会了 JavaScript 中两个最重要的编程概念:
- 函数:用
function关键字定义,通过函数名加括号调用。可以带参数(接收输入),可以有返回值(return交出结果)。函数让代码可复用、可维护。 - 条件判断:
if...else if...else根据不同的条件执行不同的代码。条件由比较运算符(>、<、===等)和逻辑运算符(&&、||、!)构成。 prompt():弹出输入框获取用户输入,返回值是字符串,做数学运算前需要用Number()转换。isNaN():检查一个值是否为“非数字”,常用于验证用户输入。Math.random()和Math.floor():生成随机整数。
“猜数字”小游戏虽然简单,但它包含了编程的完整骨架:数据结构、用户输入、条件判断、状态管理、界面更新。把这个例子吃透,你就具备了写更复杂交互的能力。
下一篇预告
下一篇,我们将做一个综合实战项目——从零搭建一个带交互的个人名片页面。你将综合运用 HTML 结构、CSS 布局与样式、JavaScript 交互三者,把前面八篇所学的知识全部串联起来。这将是你前端学习之路上第一个完整的作品。
前端·零基础入门专题,每周更新。













暂无评论内容