
摘要 程序不是从上到下直线运行的。本篇将全面掌握 JavaScript 的决策和循环逻辑if/else、switch、for、while 以及现代的 for...of 循环。随后我们将深入函数的定义与调用、参数与返回值、箭头函数并揭开作用域和闭包的神秘面纱。最后用一场“猜数字”游戏把所学知识串联起来体验到编程的乐趣与成就感。一、条件语句让代码学会做决定1.1 if / else if / else这是最直观的决策结构。const score 85; if (score 90) { console.log(优秀); } else if (score 75) { console.log(良好); } else if (score 60) { console.log(及格); } else { console.log(需要加油哦); } // 输出良好条件表达式会被隐式转换为布尔值所以我们可以利用真假值const userInput ; // 空字符串为 falsy if (userInput) { console.log(输入有效); } else { console.log(输入不能为空); }1.2 三元运算符? :对于简单的条件赋值可以用更简洁的三元运算符const age 20; const canVote (age 18) ? 可以投票 : 还不能投票; console.log(canVote); // 可以投票它相当于if...else的简写但不可嵌套太深以免降低可读性。1.3 switch 语句当有多个确定值要判断时switch比多条else if更清晰const day 3; let dayName; switch (day) { case 1: dayName 星期一; break; case 2: dayName 星期二; break; case 3: dayName 星期三; break; case 4: dayName 星期四; break; case 5: dayName 星期五; break; case 6: case 7: dayName 周末; break; default: dayName 未知; } console.log(dayName); // 星期三特别提醒每个case末尾的break至关重要如果忘记写会发生“贯穿” (fall-through)即会继续执行下一个case的代码。有时我们刻意利用贯穿但绝大部分时候要记得加break。二、循环重复工作的自动化循环就是反复执行同一段代码直到条件不满足为止。2.1 for 循环最经典的循环通常用于已知次数。// 打印 0 到 4 for (let i 0; i 5; i) { console.log(当前 i 的值为${i}); } // 初始化表达式let i 0 只执行一次 // 条件表达式i 5 每次循环前检查 // 更新表达式i 每次循环结束后执行 //for 循环常用于遍历数组 const fruits [苹果, 香蕉, 橘子]; for (let i 0; i fruits.length; i) { console.log(fruits[i]); }2.2 while 与 do...while当不确定循环次数时可用while。// 持续掷骰子直到掷出 6 let dice 0; while (dice ! 6) { dice Math.ceil(Math.random() * 6); console.log(掷出了 ${dice}); } console.log(终于掷出6了);do...while保证循环体至少执行一次因为条件判断在末尾。let input; do { input prompt(请输入退出); // 浏览器环境 } while (input ! 退出);2.3 for...of 与 for...inES6 带来了更简洁的遍历方式。for...of遍历可迭代对象数组、字符串、Map、Set 等的值。const colors [红, 黄, 蓝]; for (const color of colors) { console.log(color); // 红, 黄, 蓝 }for...in遍历对象的可枚举属性键常用于对象但会遍历原型链使用时小心通常配合hasOwnProperty。建议遍历数组时不要用for...in因为顺序不保证且会包含非索引属性。const person { name: 小明, age: 18 }; for (const key in person) { console.log(${key}: ${person[key]}); }2.4 跳出循环break 与 continuebreak彻底终止整个循环。continue跳过本次循环的剩余部分直接进入下一次迭代。for (let i 0; i 10; i) { if (i 3) continue; // 跳过 3 if (i 7) break; // 在 7 处终止 console.log(i); // 0,1,2,4,5,6 }三、函数封装可复用的逻辑块函数就是一组可重复调用的代码。DRY 原则Dont Repeat Yourself的核心工具。3.1 函数声明与调用// 定义函数 function greet(name) { return 你好${name}; } // 调用函数 const message greet(小白); console.log(message); // 你好小白3.2 参数与返回值函数可以有多个参数也可以没有。return语句将值返回给调用者并立刻结束函数执行。function add(a, b) { return a b; console.log(这行不会执行); }ES6 引入了默认参数function power(base, exponent 2) { return base ** exponent; } console.log(power(5)); // 25 (平方) console.log(power(5, 3)); // 125 (立方)3.3 函数表达式与箭头函数函数在 JavaScript 中是一等公民可以赋值给变量。// 匿名函数表达式 const sayHi function(name) { return Hi, ${name}; }; // 箭头函数 (ES6) const sayHello (name) { return Hello, ${name}; }; // 更简洁的写法只有一个参数可省略括号函数体只有一句 return 可省略花括号和 return const greeting name Hey, ${name}; console.log(greeting(世界)); // Hey, 世界箭头函数不只是写法简洁它没有自己的this会捕获外层上下文的this这在 DOM 事件和对象方法中有重要影响我们后续详谈。四、作用域与闭包4.1 作用域类型作用域决定了变量的可访问范围。ES6 之前只有全局作用域和函数作用域let和const带来了块级作用域。// 全局作用域 let globalVar 我是全局的; function testScope() { // 函数作用域 let funcVar 我在函数里; if (true) { // 块级作用域 let blockVar 我在代码块里; var notBlock 我是 var无视块; console.log(blockVar); // 可以访问 } console.log(notBlock); // 可以访问因为 var 不识别块作用域 // console.log(blockVar); // ❌ 报错blockVar 在块外不可见 }作用域链内部作用域能访问外部作用域的变量反之不行。这像一层层嵌套的盒子内层可以看外层。4.2 闭包 (Closure)闭包是 JavaScript 最强大的特性之一。当函数可以记住并访问它被创建时的词法作用域即使这个函数在其他地方被调用就产生了闭包。function createCounter() { let count 0; // 这个变量被内部函数引用形成闭包 return function() { count; console.log(count); }; } const counter createCounter(); counter(); // 1 counter(); // 2 // counter 函数依然可以访问和修改 count但外部无法直接触碰 count闭包常用于数据私有化、创建模块、事件处理函数中保留循环变量等。我们会在实战项目中反复使用。五、实战项目猜数字游戏让我们把条件、循环、函数和作用域结合起来编写一个完整的浏览器猜数字游戏。需求程序随机生成 1-100 之间的整数用户在输入框猜数字页面给出“大了”、“小了”或“猜对了”的反馈并记录猜的次数。HTML 结构 (guess.html)!DOCTYPE html html langzh head meta charsetUTF-8 title猜数字游戏/title /head body h2 猜数字 (1-100)/h2 input typenumber idguessInput placeholder输入你的猜测 button idsubmitBtn猜/button p idmessage/p p idattempts已猜次数0/p script srcguess.js/script /body /htmlJavaScript (guess.js)// 立即执行函数创建一个私有作用域避免全局污染 (function() { // 私有变量 const secretNumber Math.floor(Math.random() * 100) 1; let attempts 0; // 获取 DOM 元素 const guessInput document.getElementById(guessInput); const submitBtn document.getElementById(submitBtn); const messageEl document.getElementById(message); const attemptsEl document.getElementById(attempts); // 核心游戏逻辑函数 function checkGuess() { const userGuess Number(guessInput.value); if (!userGuess || userGuess 1 || userGuess 100) { messageEl.textContent ⚠️ 请输入 1~100 之间的有效数字; return; } attempts; attemptsEl.textContent 已猜次数${attempts}; if (userGuess secretNumber) { messageEl.textContent 恭喜你答案就是 ${secretNumber}你用了 ${attempts} 次猜对; // 猜对后禁止继续 submitBtn.disabled true; guessInput.disabled true; } else if (userGuess secretNumber) { messageEl.textContent 大了再试试。; } else { messageEl.textContent 小了再试试。; } guessInput.value ; guessInput.focus(); } // 绑定事件 submitBtn.addEventListener(click, checkGuess); guessInput.addEventListener(keypress, function(e) { if (e.key Enter) { checkGuess(); } }); })();解析外层(function(){...})()是一个立即执行函数表达式 (IIFE)内部变量secretNumber和attempts不会泄露到全局这就是利用函数作用域和闭包实现数据私有。Math.random()生成 0-1 随机数乘以 100 再取整并加一得到 1-100。事件监听使程序响应用户交互是 Web 开发的核心模式。通过条件判断给出不同反馈循环体现在用户可以反复猜直到猜对。总结 本篇我们让代码具备了决策条件语句和重复执行循环的能力并学会了如何把逻辑封装进可复用的函数中。作用域和闭包是 JavaScript 的精髓理解了它们才能迈向中高级。猜数字游戏虽小但已包含了完整应用的基本骨架数据结构、业务逻辑、DOM 操作和事件响应。如果这篇文章帮你解决了实操上的困惑别忘记点击点赞、分享也可以留言告诉我你遇到的其它问题我会尽快回复。动手练习是掌握编程最快的方法请务必亲手敲一遍本文的所有示例代码并截图保存你的成果。你的关注是我坚持原创和细节共享的力量来源谢谢大家。