最近两天在读vue源码时,看到cached方法,如下:
/**
* Create a cached version of a pure function.
*/
export function cached<F: Function> (fn: F): F {
const cache = Object.create(null)
return (function cachedFn (str: string) {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}: any)
}
或
/**
* Create a cached version of a pure function.
*/
function cached(fn) {
var cache = Object.create(null);
return (function cachedFn(str) {
var hit = cache[str];
return hit || (cache[str] = fn(str))
})
}
一开始没太看明白把函数包装一次有什么用处,网上找了下资料, https://segmentfault.com/q/1010000013629607/a-1020000013629988 这里有提到 cached会把fn的执行结果缓存起来,下次直接返回。看到这里这个函数做什么的基本 就了然了。然后顺手写了个小示例,结果发现个小问题。
代码如下:
function cached(fn) {
var cache = Object.create(null)
return (function cachedFn(str) {
var hit = cache[str]
return hit !== undefined ? hit : (cache[str] = fn(str))
})
}
function findPrime(num) {
num = BigInt(num)
var result = true
for (var i = 2n; i < num; i++) {
if (num % i === 0n) {
result = false
}
}
return result
}
var isPrime1 = function (nn) {
var t1 = new Date()
var result = findPrime(nn)
var t2 = new Date()
console.log('Use time: ', t2.getTime() - t1.getTime())
return result
}
var findPrime2 = cached(findPrime)
var isPrime2 = function (nn) {
var t1 = new Date()
var result = findPrime2(nn)
var t2 = new Date()
console.log('Use time: ', t2.getTime() - t1.getTime())
return result
}
isPrime1(8271212n)
>> Use time: 1516
>> false
isPrime1(8271212n)
>> Use time: 1503
>> false
//////////////////////////////
isPrime2(8271212n)
>> Use time: 1503
>> false
isPrime2(8271212n)
>> Use time: 0
>> false
原代码中的 return hit || (cache[str] = fn(str))
在fn返回值是布尔值或者数字时,
运算结果有可能不会被缓存,比如返回 false 或 0 时,遂做了一点小修改 return hit !== undefined ? hit : (cache[str] = fn(str))
以兼容上面的情况。