高阶函数是指接受函数作为参数或返回函数作为结果的函数。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
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);
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);
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
const numbers = [1, 2, 3];
numbers.forEach(function(num) {
console.log(num);
});
// 1
// 2
// 3
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' }
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']
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
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
// 防抖:延迟执行,在连续触发时只执行最后一次
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));