JavaScript函数是“一等公民”,可赋值、传参、返回;函数声明会提升,表达式不会;推荐优先用表达式(尤其箭头函数);默认参数、解构、剩余参数提升复用性;闭包是复用核心,能捕获外部变量生成定制行为。

JavaScript 中的函数不是语法糖,而是“一等公民”——能赋值给变量、作为参数传入、从函数里返回。这意味着函数定义和调用方式直接影响代码是否真正可复用,而不是表面看起来“抽出来就能用”。
函数声明 vs 函数表达式:执行时机决定能否提前调用
函数声明(function foo() {})会被提升(hoisted),可在定义前调用;函数表达式(const foo = function() {} 或 const foo = () => {})不会,否则报 ReferenceError: Cannot access 'foo' before initialization。
实际开发中,推荐优先用函数表达式(尤其箭头函数),避免因提升导致逻辑混乱;只有需要在定义前调用时,才用函数声明。
- 函数声明适合模块初始化阶段的入口函数
- 函数表达式更适合事件回调、数组方法参数(如
map、filter) - 箭头函数不绑定
this,不能用作构造函数,也不支持arguments对象
参数处理:默认值、剩余参数与解构让复用更灵活
硬编码参数个数会锁死调用方式。用默认参数和 ...rest 可适配多种场景,比如封装一个通用请求函数:
立即学习“Java免费学习笔记(深入)”;
const apiCall = (url, { method = 'GET', headers = {}, timeout = 5000 } = {}) => {
// 实际 fetch 逻辑
};
这样调用时可省略配置项:apiCall('/users'),也可精细控制:apiCall('/posts', { method: 'POST', timeout: 10000 })。
- 对象解构 + 默认值比一堆
if (options.method) ...更简洁安全 -
...args适合代理调用(如包装console.log加时间戳) - 避免在默认值里写副作用逻辑(如
defaultVal = heavyCalc()),它会在每次调用时执行
闭包是复用的核心机制,不是高级技巧
函数复用不只是“把代码包起来”,而是利用闭包捕获外部变量,生成定制行为。例如创建带固定前缀的日志函数:
const createLogger = (prefix) => (msg) => console.log(`[${prefix}] ${msg}`);
const errorLog = createLogger('ERROR');
const infoLog = createLogger('INFO');
errorLog('file not found'); // [ERROR] file not found
这里 prefix 被闭包保留,每个生成的函数都拥有独立上下文。这种模式比反复传 prefix 参数更可靠,也更容易测试。
- 闭包会持有对外部作用域的引用,不当使用可能引发内存泄漏(如缓存大量 DOM 节点)
- 不要在循环中直接用
var声明的变量创建闭包,容易所有函数共享同一个值;用let或显式传参解决
真正可复用的函数,往往不靠文档说明“怎么用”,而靠签名清晰、副作用可控、边界明确。比如一个纯函数(相同输入永远返回相同输出,不修改外部状态),哪怕没注释,也能放心复用;反之,一个依赖全局 document 或修改传入对象的函数,再“通用”也得加隔离层。











