惰性函数是在首次调用时完成初始化并重写自身、后续调用直接执行优化逻辑的函数;它通过首次判断环境后替换函数引用,避免重复检测开销,适用于高频调用且判断逻辑较重的场景。

惰性函数(Lazy Function)是指在**首次调用时才完成初始化或重写自身**的函数,后续调用直接走优化后的逻辑。它不是“延迟执行”,而是“首次执行时自我改造”,从而避免重复判断或初始化开销。
怎么实现惰性函数
核心思路:函数第一次运行时,检测环境或条件,然后用一个更高效的新函数覆盖自己(通过重新赋值函数名或闭包变量)。
- 利用函数可被重新赋值的特性(如挂载在对象上或使用 let/const 声明的变量)
- 首次调用中判断一次,比如检测浏览器是否支持某个 API、是否已加载某模块、是否需要 polyfill
- 判断完成后,把函数体替换成精简版,之后每次调用都不再做判断
常见写法示例(兼容性检测场景):
let addEvent = function(element, type, handler) {
// 首次调用:检测并重写自身
if (window.addEventListener) {
addEvent = function(element, type, handler) {
element.addEventListener(type, handler, false);
};
} else if (window.attachEvent) {
addEvent = function(element, type, handler) {
element.attachEvent('on' + type, handler);
};
} else {
addEvent = function(element, type, handler) {
element['on' + type] = handler;
};
}
// 立即执行新函数(保证首次调用也生效)
return addEvent(element, type, handler);
};
更现代的写法(用闭包 + 自执行,避免污染全局):
立即学习“Java免费学习笔记(深入)”;
const addEvent = (function() {
if (window.addEventListener) {
return function(element, type, handler) {
element.addEventListener(type, handler, false);
};
} else if (window.attachEvent) {
return function(element, type, handler) {
element.attachEvent('on' + type, handler);
};
} else {
return function(element, type, handler) {
element['on' + type] = handler;
};
}
})();
惰性函数的优点
它解决的是“每次调用都做相同判断”的低效问题,优势集中在性能和可维护性上:
- 减少运行时判断次数:环境检测、特性检查只做一次,后续调用零开销
- 提升高频调用函数的性能:比如事件绑定、DOM 创建、格式化工具等被反复使用的函数
- 代码更干净:初始化逻辑和主逻辑分离,主函数体不掺杂 if-else 分支
- 天然支持按需加载:可以结合 import() 在首次调用时动态加载模块,之后复用
适用场景提醒
不是所有函数都适合惰性化:
- 调用频次很低(比如页面只执行一次的初始化函数),惰性收益几乎为零
- 判断逻辑本身很轻(如只是 typeof 检查),重写函数的开销可能反而更高
- 需要保持函数引用不变的场景(如已被传入回调、绑定 this 或用于装饰器),重写会破坏引用
基本上就这些。惰性函数本质是“用空间换时间”的小技巧,关键在识别出那个“每次都一样但总要判断”的点,把它拎出来做一次性的自我升级。











