第八篇:JavaScript 入门(下)——函数与控制流

一、回顾与本篇目标

在上一篇中,你学会了用 JavaScript 操作页面元素:获取元素、修改文字、改变样式、响应点击事件。你已经能做出点击按钮切换内容的小交互了。

但你可能发现了一个问题:如果多个按钮要做类似的事情,代码就得写很多遍,改起来也很麻烦。而且,你只能做“如果 A 就做 B”的简单判断,遇到多种情况就不知道怎么处理了。

这一篇,我们要学两个让代码更强大、更优雅的核心概念:函数控制流。函数让你把代码打包成可复用的模块,控制流让你能根据不同的条件执行不同的代码。

本篇的目标:

  1. 理解函数的本质,学会定义带参数的函数
  2. 掌握 if...else if...else 多分支条件判断
  3. 学会用 prompt() 让用户输入数据
  4. 综合运用所学,做出一个“猜数字”小游戏

二、函数:把代码打包成可复用的模块

为什么需要函数

前面我们写的代码有个问题:每次做类似的事情,都要把相同的代码再写一遍。

// 没有函数:修改三个元素,代码重复
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):定义函数时括号里的变量名(nameagecity),用来占位。
  • 实参(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 的两个作用:

  1. 把函数内部计算的结果传递出去
  2. 立即结束函数的执行。return 后面的代码不会运行。

函数实战:用函数改写重复代码

回顾开头的痛点,用函数改写:

// 定义一个函数:把指定元素变成红色
function makeRed(elementId) {
  document.getElementById(elementId).style.color = 'red';
}

// 简洁的调用
makeRed('el1');
makeRed('el2');
makeRed('el3');
makeRed('el100');  // 再多的元素也不怕

这就是函数的核心价值:一次定义,重复使用,修改一处,全部生效

三、条件判断:让代码有选择能力

if...else:二选一

上一篇文章我们已经用了 if...else,现在来深入理解它的语法:

if (条件) {
  // 条件成立时执行
} else {
  // 条件不成立时执行
}

条件:写在括号里的表达式,结果必须是布尔值 truefalse

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:猜数字游戏改造

打开第五节的综合代码,做以下改造:

  1. 把最大猜测次数从 7 改为 10。
  2. 把数字范围从 1-100 改为 1-50(同时修改 prompt 提示文字、验证范围、随机数生成逻辑)。
  3. 增加一个“显示答案”的调试按钮,点击后在控制台输出当前秘密数字。
  4. 当用户猜错时,除了提示“太大”或“太小”,还显示“你猜的数字是 XX”。

七、本篇小结

这一篇你学会了 JavaScript 中两个最重要的编程概念:

  • 函数:用 function 关键字定义,通过函数名加括号调用。可以带参数(接收输入),可以有返回值return 交出结果)。函数让代码可复用、可维护。
  • 条件判断if...else if...else 根据不同的条件执行不同的代码。条件由比较运算符(><=== 等)和逻辑运算符(&&||!)构成。
  • prompt():弹出输入框获取用户输入,返回值是字符串,做数学运算前需要用 Number() 转换。
  • isNaN():检查一个值是否为“非数字”,常用于验证用户输入。
  • Math.random()Math.floor():生成随机整数。

“猜数字”小游戏虽然简单,但它包含了编程的完整骨架:数据结构、用户输入、条件判断、状态管理、界面更新。把这个例子吃透,你就具备了写更复杂交互的能力。

下一篇预告

下一篇,我们将做一个综合实战项目——从零搭建一个带交互的个人名片页面。你将综合运用 HTML 结构、CSS 布局与样式、JavaScript 交互三者,把前面八篇所学的知识全部串联起来。这将是你前端学习之路上第一个完整的作品。

前端·零基础入门专题,每周更新。

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容