JavaScript 函数
核心基础 JavaScript Functions一、为什么需要函数
1.1 问题:代码重复
想象一个 家务机器人,每天需要执行买牛奶的流程:
javascript
alert("leaveHouse");
alert("moveRight");
alert("moveRight");
alert("moveUp");
alert("moveUp");
alert("moveUp");
alert("moveUp");
alert("buyMilk");
alert("moveDown");
// ... 还有更多如果每天都要重新写一遍,效率极低。
1.2 解决方案:封装为函数
把一系列指令 打包 成一个可复用的代码块:
javascript
function getMilk() {
console.log("leaveHouse");
console.log("moveRight");
console.log("moveRight");
console.log("buyMilk");
console.log("moveLeft");
console.log("moveLeft");
console.log("enterHouse");
}
getMilk(); // 一行代码执行所有步骤
getMilk(); // 可以重复调用二、函数的三种形态 🍦
就像经典 Neapolitan 冰淇淋有三种口味,函数也有三种形态:
2.1 🍦 Vanilla — 基本函数(无输入无输出)
最简单的函数,只包装一组固定指令。
javascript
// 创建函数
function getMilk() {
console.log("Go to store");
console.log("Buy milk");
console.log("Come back");
}
// 调用函数
getMilk();语法结构:
| 组成部分 | 作用 |
|---|---|
function | 关键字,声明要创建函数 |
getMilk | 函数名(遵循驼峰命名) |
() | 圆括号(此处为空,无参数) |
{...} | 花括号,包裹函数体 |
创建 vs 调用
- 创建:需要
function关键字 + 花括号 - 调用:只写函数名 + 圆括号 + 分号:
getMilk();
2.2 🍫 Chocolate — 带参数的函数(有输入)
函数可以接收 输入(参数),并在内部使用:
javascript
function getMilk(bottles) {
var cost = bottles * 1.5;
console.log("Buy " + bottles + " bottles of milk");
console.log("Total cost: $" + cost);
}
getMilk(2); // bottles = 2, cost = $3.0
getMilk(5); // bottles = 5, cost = $7.5术语区分:
| 术语 | 位置 | 示例 |
|---|---|---|
| 参数 (Parameter) | 函数定义中 | function getMilk(bottles) 中的 bottles |
| 实参 (Argument) | 函数调用时 | getMilk(2) 中的 2 |
2.3 多参数
函数可以接收 多个参数,用逗号分隔:
javascript
function getMilk(money, costPerBottle) {
var numberOfBottles = Math.floor(money / costPerBottle);
console.log("Buy " + numberOfBottles + " bottles of milk");
}
getMilk(10, 1.5); // 可以买 6 瓶
getMilk(5, 2.0); // 可以买 2 瓶2.4 🍓 Strawberry — 带返回值的函数(有输入有输出)
使用 return 关键字让函数 输出 一个值:
javascript
function getMilk(money) {
var numberOfBottles = Math.floor(money / 1.5);
console.log("Buy " + numberOfBottles + " bottles");
return money % 1.5; // 返回找零
}
var change = getMilk(4);
console.log("Change: $" + change); // Change: $1工作流程:
- 调用
getMilk(4)→money = 4 - 计算
numberOfBottles = Math.floor(4 / 1.5)→2 return 4 % 1.5→ 输出1change = 1
return 的作用
return 让函数的调用表达式 变成一个值,可以被赋给变量、传入其他函数或参与运算。
三、函数嵌套与模块化
3.1 函数调用函数
可以在一个函数内 调用 另一个函数,实现模块化:
javascript
function calcBottles(startingMoney, costPerBottle) {
var numberOfBottles = Math.floor(startingMoney / costPerBottle);
return numberOfBottles;
}
function calcChange(startingAmount, costPerBottle) {
var change = startingAmount % costPerBottle;
return change;
}
function getMilk(money, costPerBottle) {
console.log("Buy " + calcBottles(money, costPerBottle) + " bottles");
return calcChange(money, costPerBottle);
}
var change = getMilk(10, 1.5);
console.log("Here is your $" + change + " change.");3.2 模块化的好处
- 可复用:
calcBottles()可以在任何需要计算数量的地方使用 - 易维护:如果计算逻辑变了,只需修改一处
- 易调试:可以单独测试每个小函数
四、console.log vs alert
| 特性 | alert() | console.log() |
|---|---|---|
| 可见对象 | 用户(网站访客) | 开发者 |
| 呈现方式 | 弹窗对话框 | 控制台文本 |
| 使用场景 | 需要用户交互 | 调试、测试、日志 |
| 阻断性 | 阻断执行,需点击 OK | 不阻断 |
javascript
// 用户可见
alert("Welcome!");
// 仅开发者可见(F12 → Console)
console.log("Debug: user logged in");五、Karel 机器人练习
Karel the Robot 是 Stanford 的教学工具,用于练习 函数抽象 思维。
5.1 基本命令
| 命令 | 功能 |
|---|---|
move() | 向前移动一格 |
turnLeft() | 左转 90° |
putBeeper() | 放下标记 |
pickBeeper() | 捡起标记 |
5.2 函数抽象示例
javascript
// 将重复动作封装为函数
function moveFourTimes() {
move();
move();
move();
move();
}
// 主程序变得简洁
function main() {
moveFourTimes();
turnLeft();
moveFourTimes();
}5.3 对角线放置标记
javascript
function diagonalMoveAndBeeper() {
move();
turnLeft();
move();
putBeeper();
turnRight();
}
function main() {
putBeeper();
diagonalMoveAndBeeper();
diagonalMoveAndBeeper();
diagonalMoveAndBeeper();
diagonalMoveAndBeeper();
}六、实战练习
6.1 BMI 计算器
javascript
function bmiCalculator(weight, height) {
var bmi = weight / Math.pow(height, 2);
return Math.round(bmi);
}
var bmi = bmiCalculator(65, 1.8);
console.log("Your BMI is: " + bmi); // 206.2 Life in Weeks
javascript
function lifeInWeeks(age) {
var yearsRemaining = 90 - age;
var days = yearsRemaining * 365;
var weeks = yearsRemaining * 52;
var months = yearsRemaining * 12;
console.log("You have " + days + " days, " +
weeks + " weeks, and " +
months + " months left.");
}
lifeInWeeks(25);七、Angela 的建议:正确设定预期
关于编程难度的真相
- ❌ "编程很简单,人人都能学" — 这是不负责任的说法
- ❌ "编程只有天才才能学" — 这也不对
- ✅ 编程是困难的,但通过持续努力是完全可以掌握的
没有人天生就是程序员。区别只在于 投入的练习量。