cached
栏目:
source
发布时间:2025-10-14
/**
* Create a cached version of a pure function.
*/
function cached<R>(fn: (str: string) => R): (sr: string) => R {
const cache: Record<string, R> = Object.create(null)
return function cachedFn(str: string) {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}
}
这段代码实现了一个函数结果缓存装饰器,用于优化纯函数(Pure Function)的执行效率。以下是逐层解读:
1. 核心功能
- 输入:一个接收字符串参数、返回任意类型
R
的纯函数fn
- 输出:一个带缓存功能的新函数
cachedFn
- 行为:当新函数被调用时,若传入参数
str
已在缓存中,直接返回缓存结果;否则调用原函数fn(str)
并将结果存入缓存后返回
2. 代码逐行解析
export function cached<R>(fn: (str: string) => R): (sr: string) => R {
// 创建无原型的空缓存对象(避免原型链污染)
const cache: Record<string, R> = Object.create(null)
return function cachedFn(str: string) {
// 检查缓存是否已存在
const hit = cache[str]
// 短路操作:存在缓存则直接返回,否则计算并存储
return hit || (cache[str] = fn(str))
}
}
3. 关键设计解析
缓存对象设计
使用Object.create(null)
创建无原型对象,避免toString
/hasOwnProperty
等原型方法与缓存键冲突,确保cache[str]
严格匹配用户传入的字符串。短路求值逻辑
hit || (cache[str] = fn(str))
利用了JavaScript的逻辑或特性:- 若
cache[str]
存在(非falsy
),直接返回缓存值 - 若不存在,执行
cache[str] = fn(str)
表达式(该表达式返回赋值结果),实现"计算→存储→返回"三合一操作
- 若
纯函数前提
该缓存策略严格依赖函数纯度:只有当fn
是纯函数(相同输入恒定输出)时,缓存结果才安全有效。若传入非纯函数,可能导致返回陈旧数据。
4. 典型使用场景
// 原始函数:计算字符串长度(纯函数示例)
const getLength = (str: string) => str.length
// 创建缓存版本
const cachedLength = cached(getLength)
// 首次调用:计算并缓存
cachedLength('hello') // 5(执行getLength)
// 二次调用:命中缓存
cachedLength('hello') // 5(直接返回缓存)
5. 性能优化原理
通过空间换时间策略,避免相同参数的重复计算。在字符串操作频繁的场景(如模板编译、文本处理)中,可显著提升性能。
6. 注意事项
- 缓存失效问题:当函数逻辑更新时,旧缓存不会自动清除,需手动重置缓存对象
- 内存占用:长期运行的程序中,缓存可能持续增长,需根据业务场景设置淘汰策略
- 非纯函数风险:若装饰非纯函数,会导致返回结果与预期不符
这种模式在Vue源码、Lodash的_.memoize
等场景中被广泛采用,是函数式编程中常见的性能优化手段。
本文地址:https://www.tides.cn/p_vue-source-cached