Vue源码——使一个函数具有缓存功能
这里的缓存是什么意思?
函数可以缓存一些值
如何使函数具有缓存功能?
思路
既然要把一个函数转化为有缓存功能的函数,那第一步肯定是创建一个函数,待转换函数作为参数,返回有缓存功能的函数
function cached(fn) {
return function cachedFn() {
// ...
}
}
既然有缓存功能,那就需要一个 ‘全局变量’ 来保存缓存。这里的全局变量并非我们平时说的全局变量,而是在闭包中的全局变量。补充代码。
function cached(fn) {
return function cachedFn() {
var cache = Object.create(null) // 缓存
}
}
Object.create(proto) ——> 以proto为原型创建一个对象。 当proto为null时,创建出来的是一个没有原型的空对象。
空对象.png
对象字面量.png
缓存函数缓存什么呢? it's up to you。 假设我们要缓存字符串,待缓存函数可以对这个字符串进行一系列的操作。如果缓存中有这个字符串,返回这个字符串,如果没有,往缓存中添加这个字符串并返回。举个例子
function cached(fn) {
var cache = Object.create(null)
return function cachedFn(str) {
var hit = cache[str]
return hit || (cache[str] = fn(str))
}
}
// 待缓存函数
function upperStr(str) {
return str.toUpperCase()
}
// 转换 upperStr 为缓存函数
var cacheUpperStr = cached(upperStr)
// 测试一下
var x = cacheUpperStr('a')
var y = cacheUpperStr('a')
// 打印cache
{
a: 'A'
}
思考: 为什么要缓存?
当我们对一个数据进行了处理之后, 如果以后经常需要用这个数据,放在缓存中可以避免再次进行处理,而不需要再次处理。
有人会问:那我不如把这个数据放在一个全局变量里面保存起来
我的回答是: 当代码量多时,我们应该尽量避免全局变量,或者说,我们要尽可能少去污染全局变量池
扩展
将缓存函数通用化
function cached(fn) {
var cache = Object.create(null)
return function cachedFn() {
var hit = cache[arguments[0]]
return hit || (cache[arguments[0]] = fn.call(this, ...arguments))
}
}
弊端: 待缓存函数的参数第一位是缓存中对应的key
发表评论 (审核通过后显示评论):