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()); // undefined

4 参数与实参

4.1 基本使用

function greet(firstName, lastName) { // 参数 (形参)
  return `Hello, ${firstName} ${lastName}`;
}
 
console.log(greet("John", "Doe")); // 实参: John, Doe

4.2 默认参数

function greet(name = "Guest") {
  return `Hello, ${name}`;
}
 
console.log(greet()); // Hello, Guest
console.log(greet("Anna")); // Hello, Anna

4.3 剩余参数

将多个实参收集到一个数组中

function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
 
console.log(sum(1, 2, 3, 4)); // 10

5 高阶函数

5.1 函数作为参数

function applyOperation(a, b, operation) {
  return operation(a, b);
}
 
const result = applyOperation(5, 3, (x, y) => x * y);
console.log(result); // 15

5.2 函数作为返回值

function multiplyBy(factor) {
  return function(number) {
    return number * factor;
  };
}
 
const double = multiplyBy(2);
console.log(double(5)); // 10
console.log(multiplyBy(3)(4)); // 12

5.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); // 6

6 立即执行函数

定义后立即执行,常用于创建独立作用域。

(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 解决。