高阶函数是接受函数作为参数或返回函数作为结果的函数。如map、filter、reduce、setTimeout、Promise.then等内置方法,以及自定义的logAfter、createMultiplier和addEventListener均属此类,体现函数作为值传递与延迟执行特性。

高阶函数不是“高级”的函数,而是指**接受函数作为参数、或返回函数作为结果**的函数。这是 JavaScript 函数式编程的基础特征,不是语法糖,而是语言原生支持的能力。
哪些内置函数是典型的高阶函数
JavaScript 运行时自带多个高频使用的高阶函数,它们都接收 callback(回调函数)作为参数:
-
Array.prototype.map():对每个元素调用传入的函数,返回新数组 -
Array.prototype.filter():用传入函数判断真假,保留为true的元素 -
Array.prototype.reduce():用传入的累加器函数合并所有元素 -
setTimeout()和setInterval():第一个参数必须是函数 -
Promise.then()和Promise.catch():接收处理函数,不是值
注意:forEach() 也是,但它不返回新数组,所以不适合链式调用;而 map() 和 filter() 返回新数组,天然适合组合使用。
自己写的函数怎么变成高阶函数
只要函数签名里出现函数类型的参数,或者 return 一个函数,它就是高阶函数。常见写法有两类:
立即学习“Java免费学习笔记(深入)”;
- 接收函数作为参数:
function logAfter(fn) { return function(...args) { console.log('run'); return fn(...args); }; } - 返回函数(即“函数工厂”):
function createMultiplier(n) { return function(x) { return x * n; }; },调用createMultiplier(3)(4)得到12
这类写法常用于封装逻辑复用,比如权限校验、日志埋点、防抖节流——但要注意闭包中变量的生命周期,避免意外持有大对象。
为什么 addEventListener 是高阶函数但容易被忽略
因为它的第二个参数明确要求是 EventListener 类型(即函数),而且这个函数会在未来某个事件触发时被调用。它典型体现了“函数作为值传递 + 延迟执行”的高阶特性:
- 你传进去的不是执行结果,而是“将来要怎么处理”的定义
- 这个函数可以访问定义时的作用域(闭包),比如
let id = 1; btn.addEventListener('click', () => console.log(id)) - 如果传的是箭头函数且依赖外部变量,又在循环中注册,容易因变量提升导致所有监听器共享最后一个值——这是最常见的坑
真正难的不是写出高阶函数,而是判断何时该把逻辑抽成函数传入,何时该提前执行;更关键的是,理解函数被传入后,它的 this、作用域和调用时机是否符合预期。











