icon
高阶函数

高阶函数

高阶函数是指接受函数作为参数或返回函数作为结果的函数。JavaScript 中的函数是一等公民,可以作为值传递。

基本概念

// 接受函数作为参数
function higherOrderFunc(callback) {
  callback();
}

higherOrderFunc(function() {
  console.log('Hello');
});

// 返回函数
function createMultiplier(multiplier) {
  return function(number) {
    return number * multiplier;
  };
}

const double = createMultiplier(2);
console.log(double(5)); // 10

常见的高阶函数

  1. map
    • 对数组每个元素执行函数,返回新数组
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(function(num) {
  return num * 2;
});
console.log(doubled); // [2, 4, 6, 8]

// 箭头函数写法
const doubled2 = numbers.map(num => num * 2);
  1. filter
    • 过滤数组元素,返回满足条件的元素组成的新数组
const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(function(num) {
  return num % 2 === 0;
});
console.log(evens); // [2, 4]

const evens2 = numbers.filter(num => num % 2 === 0);
  1. reduce
    • 将数组归约为单个值
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce(function(acc, num) {
  return acc + num;
}, 0);
console.log(sum); // 10

// 计算乘积
const product = numbers.reduce((acc, num) => acc * num, 1);
console.log(product); // 24
  1. forEach
    • 遍历数组,执行函数,不返回新数组
const numbers = [1, 2, 3];
numbers.forEach(function(num) {
  console.log(num);
});
// 1
// 2
// 3
  1. find
    • 查找第一个满足条件的元素
const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
];

const user = users.find(function(u) {
  return u.id === 2;
});
console.log(user); // { id: 2, name: 'Bob' }
  1. some / every
    • some: 至少有一个元素满足条件
    • every: 所有元素都满足条件
const numbers = [1, 2, 3, 4];
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true

const allPositive = numbers.every(num => num > 0);
console.log(allPositive); // true

函数组合

高阶函数可以组合使用,实现复杂的数据处理:

const users = [
  { name: 'Alice', age: 25, active: true },
  { name: 'Bob', age: 30, active: false },
  { name: 'Charlie', age: 35, active: true }
];

// 链式调用
const activeUserNames = users
  .filter(user => user.active)
  .map(user => user.name)
  .sort();

console.log(activeUserNames); // ['Alice', 'Charlie']

自定义高阶函数

  1. 函数装饰器
function logDecorator(func) {
  return function(...args) {
    console.log('调用函数:', func.name);
    console.log('参数:', args);
    const result = func.apply(this, args);
    console.log('结果:', result);
    return result;
  };
}

function add(a, b) {
  return a + b;
}

const loggedAdd = logDecorator(add);
loggedAdd(2, 3);
// 调用函数: add
// 参数: [2, 3]
// 结果: 5
  1. 函数柯里化
function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...nextArgs) {
        return curried.apply(this, args.concat(nextArgs));
      };
    }
  };
}

function add(a, b, c) {
  return a + b + c;
}

const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6
console.log(curriedAdd(1)(2, 3)); // 6
  1. 防抖和节流
// 防抖:延迟执行,在连续触发时只执行最后一次
function debounce(func, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

// 节流:限制执行频率,每隔一段时间执行一次
function throttle(func, delay) {
  let lastCall = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastCall >= delay) {
      lastCall = now;
      return func.apply(this, args);
    }
  };
}

// 使用示例
const debouncedSearch = debounce(function(query) {
  console.log('搜索:', query);
}, 300);

const throttledScroll = throttle(function() {
  console.log('滚动事件');
}, 100);

函数式编程思想

高阶函数是函数式编程的基础:

// 函数组合
function compose(...fns) {
  return function(value) {
    return fns.reduceRight((acc, fn) => fn(acc), value);
  };
}

const addOne = x => x + 1;
const multiplyTwo = x => x * 2;
const square = x => x * x;

const composed = compose(square, multiplyTwo, addOne);
console.log(composed(3)); // ((3 + 1) * 2) ^ 2 = 64

// 管道(从左到右)
function pipe(...fns) {
  return function(value) {
    return fns.reduce((acc, fn) => fn(acc), value);
  };
}

const piped = pipe(addOne, multiplyTwo, square);
console.log(piped(3)); // ((3 + 1) * 2) ^ 2 = 64

实际应用

// 数据处理管道
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const result = data
  .filter(x => x % 2 === 0)      // 筛选偶数
  .map(x => x * x)                // 平方
  .reduce((sum, x) => sum + x, 0); // 求和

console.log(result); // 220

// 异步操作链
function fetchUser(id) {
  return Promise.resolve({ id, name: `User${id}` });
}

function fetchPosts(userId) {
  return Promise.resolve([
    { id: 1, userId, title: 'Post 1' },
    { id: 2, userId, title: 'Post 2' }
  ]);
}

fetchUser(1)
  .then(user => fetchPosts(user.id))
  .then(posts => posts.map(post => post.title))
  .then(titles => console.log(titles));