函数表达式作参数时不自动执行,是否及何时执行取决于接收函数;写fn是传引用,fn()才调用;匿名函数可直接传参,如setTimeout或addEventListener中的回调。

函数表达式作为参数传递时,不会自动执行,是否运行、何时运行、怎么运行,全看接收它的那个函数怎么写。
函数表达式本身是值,不是调用
写 fn 是引用函数,写 fn() 才是调用。传参时只写函数名(或匿名函数字面量),它就只是个值,就像传一个数字或字符串那样被对待。
- 例如:
setTimeout(function(){ console.log('hello'); }, 1000)—— 这里传进去的是一个函数表达式,但没加括号,所以没执行;setTimeout内部会在 1 秒后自己调用它 - 而如果写成
setTimeout(function(){ console.log('hello'); }(), 1000),括号紧挨着,那这个函数表达式会在传参前就立刻执行,返回值(通常是undefined)才被传给setTimeout,结果什么也不会延迟打印
匿名函数表达式可直接传,无需先命名
函数表达式支持直接在调用位置定义,比如作为回调传入 map、filter 或事件监听器中,语法简洁且作用域干净。
-
[1,2,3].map(function(x){ return x * 2; })→ 返回[2,4,6] -
button.addEventListener('click', function(){ alert('clicked'); })—— 点击时才执行 - 注意:这种写法下,函数没有名字,调试时堆栈里可能显示为
anonymous或function
传参后能否修改?取决于宿主函数逻辑
函数表达式作为参数,本质是把函数对象的引用传过去。接收方可以存起来、延迟调用、多次调用,也可以不调用——它完全自由。
立即学习“Java免费学习笔记(深入)”;
- 像
console.log(myFn)只是输出函数体,不触发执行 - 像
someAsyncAPI(data, myFn)可能在请求完成后再调用myFn,也可能根本不调用(比如出错提前返回) - 你不能假设“只要传了就会执行”,必须查阅该 API 文档或源码确认调用时机和条件
与函数声明在传参时表现一致,但有细微差异
函数表达式和函数声明都能作为参数传递,行为上没有区别。关键差异在于提升(hoisting):函数声明会被提升,函数表达式不会。
- 这意味着你不能在定义前就用函数表达式作为参数(会报
ReferenceError),而函数声明可以 - 但在传参那一刻,二者都已是可调用的对象,宿主函数无法分辨它是声明还是表达式


















