Skip to content

函数式编程 🎯 ​

1. 编程范式对比 ​

  • 面向过程: 按步骤顺序执行,强调动作
  • 面向对象: 以对象为中心,封装数据和行为
  • 函数式编程: 以函数为基本单位,强调数据流转换

2. 函数式编程优势 ✨ ​

  • 提高代码复用性和可维护性
  • 便于测试和调试(纯函数易于测试)
  • 有利于代码优化(Tree-shaking友好)
  • 并发安全(无副作用,减少 bug)

3. 函数式编程核心原则 📌 ​

  1. 纯函数原则
javascript
// ❌ 不纯的函数
let count = 0;
const increment = () => count++;

// ✅ 纯函数
const add = (a, b) => a + b;
  1. 避免副作用
javascript
// ❌ 有副作用
const updateUser = (user) => {
  user.name = 'New Name';  // 直接修改原对象
}

// ✅ 无副作用
const updateUser = (user) => ({
  ...user,
  name: 'New Name'  // 返回新对象
});

函数组合工具 🔧 ​

1. compose 函数 ​

将多个函数组合成一个函数,从右到左执行。

javascript
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

// 使用示例
const addOne = x => x + 1;
const double = x => x * 2;
const addOneAndDouble = compose(double, addOne);
console.log(addOneAndDouble(3)); // 8

2. pipe 函数 ​

类似 compose,但从左到右执行。

javascript
const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

高阶函数实践 💡 ​

1. 常用高阶函数实现 ​

javascript
// map 实现
Array.prototype.myMap = function(callback) {
  if (typeof callback !== 'function') {
    throw new TypeError('Callback must be a function');
  }
  const result = [];
  for (let i = 0; i < this.length; i++) {
    result.push(callback.call(this, this[i], i, this));
  }
  return result;
};

// reduce 实现
Array.prototype.myReduce = function(callback, initialValue) {
  if (typeof callback !== 'function') {
    throw new TypeError('Callback must be a function');
  }
  let accumulator = initialValue === undefined ? this[0] : initialValue;
  const startIndex = initialValue === undefined ? 1 : 0;
  
  for (let i = startIndex; i < this.length; i++) {
    accumulator = callback(accumulator, this[i], i, this);
  }
  return accumulator;
};

函数柯里化 🎨 ​

javascript
// 实现柯里化函数
const curry = (fn) => {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    }
    return (...moreArgs) => curried.apply(this, args.concat(moreArgs));
  };
};

// 使用示例
const sum = (a, b, c) => a + b + c;
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6

异步编程最佳实践 ⚡ ​

1. Promise 使用技巧 ​

javascript
// 并行执行 Promise
const fetchData = async () => {
  try {
    const [users, posts] = await Promise.all([
      fetch('/api/users'),
      fetch('/api/posts')
    ]);
    return { users, posts };
  } catch (error) {
    console.error('Error fetching data:', error);
  }
};

// Promise 超时处理
const timeoutPromise = (promise, ms) => {
  const timeout = new Promise((_, reject) => {
    setTimeout(() => reject(new Error('Timeout')), ms);
  });
  return Promise.race([promise, timeout]);
};

2. async/await 最佳实践 ​

javascript
// ✅ 正确的错误处理
async function fetchUserData() {
  try {
    const response = await fetch('/api/user');
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error:', error);
    throw error; // 重要:向上传递错误
  }
}

// ✅ 并发控制
async function processItems(items, concurrency = 2) {
  const chunks = [];
  for (let i = 0; i < items.length; i += concurrency) {
    const chunk = items.slice(i, i + concurrency);
    await Promise.all(chunk.map(item => processItem(item)));
  }
}

注意事项 ⚠️ ​

  1. 避免在循环中使用 async/await
  2. 合理使用 Promise.all() 进行并发控制
  3. 始终做好错误处理
  4. 保持函数纯净,避免副作用
  5. 合理使用函数组合,避免过度组合导致代码难以理解

总结 📝 ​

函数式编程和异步编程是现代 JavaScript 开发中的重要概念。通过合理运用这些技术,我们可以写出更加可维护、可测试的代码。记住要遵循纯函数原则,避免副作用,合理处理异步操作,这样才能构建出高质量的应用程序。