serendipityApe / javascriptPromotion

资深前端必备的编码问题
3 stars 0 forks source link

实现memo() #16

Open serendipityApe opened 3 years ago

serendipityApe commented 3 years ago

题目

Implement a general memoization function - memo()

例子

Memoization 是应用广泛的性能优化的手段,如果你开发过React应用,你一定不会对React.memo感到陌生。

那么,请实现你自己的memo() 函数。传入相同的参数的时候,直接返回上一次的结果而不经过计算。

const func = (arg1, arg2) => {
  return arg1 + arg2
}

const memoed = memo(func)

memoed(1, 2) 
// 3, func 被调用

memoed(1, 2) 
// 3,func 未被调用 

memoed(1, 3)
// 4,新参数,func 被调用

参数有可能不是字符串,所以你的memo()需要能接受第三个决定缓存key的参数,有点类似于_.memoize() 。

const memoed = memo(func, () => 'samekey')

memoed(1, 2) 
// 3,func被调用,缓存key是 'samekey'

memoed(1, 2) 
// 3,因为key是一样的,3被直接返回,func未调用

memoed(1, 3) 
// 3,因为key是一样的,3被直接返回,func未调用
默认的key可以用Array.from(arguments).join('_')。

注意

这是一种空间换时间的优化,在实际面试中,请仔细分析时间空间复杂度。

答案 function memo(func, resolver=(...args) => args.join('_')) { // your code here let cache=new Map(); return function(...args){ let cacheKey=resolver(...args); if(cache.has(cacheKey)){ return cache.get(cacheKey); } let value=func.apply(this,args); cache.set(cacheKey,value); return value; } }

补充

事实上Memoization是设计模式中的一个小分类,代理模式-缓存代理。 如果你对代理模式感兴趣的话可以看一下本人写的相关博客。 js设计模式