1 什么是函数
函数是一段可重复使用的代码块,它接受输入(参数),执行特定任务,并可以返回输出(返回值)。
生活类比:函数就像一台果汁机。你放进去水果(参数),它执行榨汁动作(代码逻辑),最后倒出果汁(返回值)。
2 定义函数的方式
JavaScript 提供了多种定义函数的方法,各有特点。
2.1 function关键字
使用 function 关键字,后跟函数名。
function greet(name) {
return "Hello, " + name + "!";
}
console.log(greet("Alice")); // Hello, Alice!特点:会被提升(hoisting),可以在声明之前调用。
sayHi("Bob"); // 正常工作: Hi, Bob!
function sayHi(name) {
console.log("Hi, " + name + "!");
}2.2 函数表达式
将函数赋值给一个变量。
const greet = function(name) {
return "Hello, " + name + "!";
};
console.log(greet("Charlie")); // Hello, Charlie!特点:不会提升,只能在定义之后使用。
2.3 箭头函数
语法更简洁,使用 ⇒。
const add = (a, b) => a + b;
console.log(add(3, 5)); // 8
// 多行语句需要花括号和 return
const multiply = (a, b) => {
let result = a * b;
return result;
};特点:
- 没有自己的 this,继承外层作用域的 this
- 不能用作构造函数 (不能 new)
- 没有 arguments 对象
3 返回值
使用 return 语句返回结果。如果没有 return,函数返回 undefined。
function noReturn() {
let x = 1;
}
console.log(noReturn()); // undefined4 参数与实参
4.1 基本使用
function greet(firstName, lastName) { // 参数 (形参)
return `Hello, ${firstName} ${lastName}`;
}
console.log(greet("John", "Doe")); // 实参: John, Doe4.2 默认参数
function greet(name = "Guest") {
return `Hello, ${name}`;
}
console.log(greet()); // Hello, Guest
console.log(greet("Anna")); // Hello, Anna4.3 剩余参数
将多个实参收集到一个数组中
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 105 高阶函数
5.1 函数作为参数
function applyOperation(a, b, operation) {
return operation(a, b);
}
const result = applyOperation(5, 3, (x, y) => x * y);
console.log(result); // 155.2 函数作为返回值
function multiplyBy(factor) {
return function(number) {
return number * factor;
};
}
const double = multiplyBy(2);
console.log(double(5)); // 10
console.log(multiplyBy(3)(4)); // 125.3 内置高阶函数示例
// map - 转换数组
const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2); // [2,4,6]
// filter - 过滤
const evens = nums.filter(n => n % 2 === 0); // [2]
// reduce - 累积
const sum = nums.reduce((acc, n) => acc + n, 0); // 66 立即执行函数
定义后立即执行,常用于创建独立作用域。
(function() {
let privateVar = "I'm private";
console.log("IIFE runs immediately");
})();
// 带参数
const result = (function(a, b) {
return a + b;
})(3, 4);
console.log(result); // 7
// 箭头函数版
(() => console.log("Arrow IIFE"))();Tip:现代替代:块级作用域 { let x = 1; } 已能实现类似隔离,但 IIFE 在旧代码中常见。
7 回调函数
将一个函数作为参数传递给另一个函数,并适当时候执行。
function fetchData(callback) {
setTimeout(() => {
const data = { name: "Alice" };
callback(data);
}, 1000);
}
fetchData((result) => {
console.log("Received:", result);
});
// 数组遍历回调
[1, 2, 3].forEach(item => console.log(item));回调地狱:过多嵌套回调导致代码难以阅读,可用 Promise/async/await 解决。