函数式编程 🎯
1. 编程范式对比
- 面向过程: 按步骤顺序执行,强调动作
- 面向对象: 以对象为中心,封装数据和行为
- 函数式编程: 以函数为基本单位,强调数据流转换
2. 函数式编程优势 ✨
- 提高代码复用性和可维护性
- 便于测试和调试(纯函数易于测试)
- 有利于代码优化(Tree-shaking友好)
- 并发安全(无副作用,减少 bug)
3. 函数式编程核心原则 📌
- 纯函数原则
javascript
// ❌ 不纯的函数
let count = 0;
const increment = () => count++;
// ✅ 纯函数
const add = (a, b) => a + b;- 避免副作用
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)); // 82. 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)));
}
}注意事项 ⚠️
- 避免在循环中使用 async/await
- 合理使用 Promise.all() 进行并发控制
- 始终做好错误处理
- 保持函数纯净,避免副作用
- 合理使用函数组合,避免过度组合导致代码难以理解
总结 📝
函数式编程和异步编程是现代 JavaScript 开发中的重要概念。通过合理运用这些技术,我们可以写出更加可维护、可测试的代码。记住要遵循纯函数原则,避免副作用,合理处理异步操作,这样才能构建出高质量的应用程序。