主题
高阶函数
高阶函数指至少满足以下一个条件的函数:
- 接收函数作为参数。
- 返回一个函数。
它是函数式编程和日常前端开发里的基础能力,不属于问答型内容,更适合作为正式专题来理解。
高阶函数解决什么问题
高阶函数的核心价值是把“行为”当成数据传来传去,从而提升复用能力。
常见场景:
- 数组处理
- 事件封装
- 防抖和节流
- 权限校验包装
- 日志、缓存、重试等通用能力包装
接收函数作为参数
最常见的高阶函数形式,是把某个处理逻辑作为参数传入。
js
function calculate(a, b, handler) {
return handler(a, b)
}
const result = calculate(1, 2, (x, y) => x + y)
console.log(result) // 3返回一个函数
如果一个函数返回另一个函数,它也是高阶函数。
js
function createAdder(base) {
return function (value) {
return base + value
}
}
const add10 = createAdder(10)
console.log(add10(5)) // 15这类写法通常会和闭包一起出现。
常见内建高阶函数
map
js
const list = [1, 2, 3]
const result = list.map((item) => item * 2)
console.log(result) // [2, 4, 6]filter
js
const list = [1, 2, 3, 4]
const result = list.filter((item) => item % 2 === 0)
console.log(result) // [2, 4]reduce
js
const list = [1, 2, 3, 4]
const result = list.reduce((total, item) => total + item, 0)
console.log(result) // 10forEach
js
;[1, 2, 3].forEach((item) => {
console.log(item)
})典型封装场景
权限校验包装
js
function withPermission(handler) {
return function (...args) {
if (!hasPermission()) {
throw new Error('No permission')
}
return handler(...args)
}
}统一日志包装
js
function withLog(handler) {
return function (...args) {
console.log('start', args)
const result = handler(...args)
console.log('end', result)
return result
}
}防抖与节流
debounce、throttle 本质上也属于返回函数的高阶函数。
和闭包的关系
高阶函数不一定等于闭包,但很多返回函数的高阶函数会天然形成闭包。
js
function createCounter() {
let count = 0
return function () {
count++
return count
}
}这里 createCounter 是高阶函数,返回的函数又借助闭包持有 count。
使用建议
- 当一段逻辑“可变”,主流程“稳定”时,优先考虑高阶函数。
- 涉及通用横切逻辑时,高阶函数通常比复制粘贴更清晰。
- 如果包装层级过深,也要警惕可读性下降。
