最近在写闭包的应用的时候,出现了一个cached函数,来源于Vue源码,利用了闭包变量不会被回收的特点,可以缓存变量,下次再调用的时候可以从缓存中读取,如果存在缓存就使用缓存,如果不存在就重新计算下,例如下面这个例子
function cached (fn) {
var cache = Object.create(null)
return (function cachedFn (str) {
var hit = cache[str];
// 看看是否有缓存
console.log('查看缓存' + cache[str]);
return hit || (cache[str] = fn(str))
})
}
var capitalize = cached(function(str) {
// 把传入参数的第一位转换为大写
return str.charAt(0).toUpperCase() + str.slice(1)
});
console.log(capitalize('abc'), '第一次')
console.log(capitalize('abc'), '第二次')
cached本质上是一个高阶函数,它接受一个函数的参数,同时返回一个函数,网上的文章基本上就说到这一句了,其实小白的我还是对整体的运行规则不太清楚,
记录下个人理解的运行过程,如果不对欢迎大佬指正
。
最开始
capitalize
会调用
cached
方法,此时
cached
中对应的参数
fn
就是在
capitalize()
中返回的方法。并且创建了一个
cache
对象用于存储缓存内容。
cached
方法中会返回一个
cachedFn
函数,这个函数用()括号包裹,并且把这个函数赋值给
capitalize
,那么此时调用
capitalize()
方法,就相当于调用
cachedFn
方法。
console.log(capitalize('abc'), '第一次')
,第一次调用
capitalize()
方法,传入的参数是
abc
,就相当于执行
cachedFn('abc')
,此时用hit保存
cache[abc]
,但此时为undefined,那么
return hit || (cache[str] = fn(str))
,就会输出
cache[str] = fn(str)
console.log(capitalize('abc'), '第二次')
,此时调用
capitalize()
方法,传入的参数也是是
abc
,通过闭包可以调用到
cache
参数,第一次最后返回的时候创建了
cache[abc]
属性,并且保存为
Abc
,那么此时
hit
就等于
Abc
,
hit
是存在的,最后
return hit || (cache[str] = fn(str))
就直接返回
hit
不用计算了
`