题目描述
思路分析
题目考察实现 memo 缓存函数,例如 React.memo(functionalComponent) 浅比对前后函数参数 props 的值,如果相同就不会执行函数。
需要定义一个闭包函数,闭包变量中存放 props,执行函数中判断变量中是否含有 props
function memo(fn) {
const map = new Map();
return function (...args) {
// 取 key
if (map.has(args)) {
return map.get(args);
}
// 赋值 key
map.set(args, fn(...args));
return fn(...args);
}
}
做到这一步,基本上实现了缓存函数,题目中还有两个要求还需要满足:
- 如果
memo函数有第二个参数callback缓存的 key 为回调函数的返回值 - 绑定 this
function memo(fn, resolver) {
const map = new Map();
return function (...args) {
// map 的 key 是引用类型会取不到值,所以 args.join() 一下
const key = resolver ? resolver(...args) : args.join('_');
// 取 key
if (map.has(key)) {
return map.get(key);
}
// 赋值 key
const cache = fn.call(this, ...args)
map.set(key, cache);
return cache;
}
}
// test1
function add(a, b) {
return a + b;
}
const memod = memo(add);
console.log(memod(1, 2));
console.log(memod(1, 2));
// test2
function funcThis(b){
return `${this.a}_${b}`;
}
const memoed = memo(funcThis);
const a = { a: 1, memoed }; // 1_2
至此,我们完成了 memo() 但是如果无限量使用 cache 会导致内存不足,所以在 memo 的基础上实现 memoize-one 仅缓存上一次的结果。
map 最多只能存在两个 map 对象,只需要在添加之前判断 map.size > 1 的情况删掉第一个缓存对象即可
// memoizeOne
if (map.size > 1) {
map.delete(map.keys().next.value);
}
AC代码
/**
* @param {Function} func
* @param {(args:[]) => string } [resolver] - cache key generator
*/
function memo(func, resolver) {
// your code here
const map = new Map();
return function (...args) {
const key = resolver ? resolver(...args) : args.join('_');
if (map.has(key)) {
console.log('is memoize', args);
return map.get(key);
}
const cache = func.call(this, ...args)
map.set(key, cache);
return cache;
}
}
总结
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情