当被记忆的函数接受函数时,Lodash会记住密钥吗?

时间:2018-03-12 21:31:17

标签: javascript optimization lodash memoization

我有一个大型数据集合,我经常通过首先应用过滤器来查询。我想缓存并重用我使用的不同过滤器函数的结果,因为这部分可能很昂贵。这是对此的粗略模拟:

const a = x => x + 1;
const b = x => x + 2;

const m = _.memoize( 
  f => (console.log('filtering data'), f(314159)),
  f => String(f)
 );

console.log(m(a));
console.log(m(b));
console.log(m(a));
console.log(m(b));

这里“a”和“b”是我想要使用的过滤器功能,“m”每次都对相同的数据起作用。

如何指定_.memoize函数的键?

上面的工作,但我正在使用感觉错误的函数的字符串表示。还有更好的方法吗?

我担心在应用缩小时这不安全。在我的实际代码中,“memoize”部分在一个ES6模块中,“a”和“b”部分在另一个模块中,对“m”的调用在几个不同的模块中导入“a”和“b” “功能。这样的模块之间的字符串表示是否稳定?是否快速转换为字符串表示?

我能想到的唯一选择是创建一个字符串 - >函数字典,所以你可以像m(“a”)那样进行调用,但如果名称错误,则不能使用JavaScript链接。

1 个答案:

答案 0 :(得分:2)

  

以上是有效的,但我正在使用感觉错误的函数的字符串表示。

确实

  

我担心在应用缩小时这不安全。

不,缩小不是问题。不同的函数被缩小为不同的代码。

问题是关闭:

const addTo = x => y => x + y
const a = addTo(1),
      b = addTo(2);
console.log(String(a) === String(b));

您只能通过对象标识可靠地比较函数。最好的方法可能是更新Lodash以使用不需要任何字符串化的ES6 WeakMap

只要没有,您可以使用

const id = Symbol("function identity");
let count = 0;
function toMemoizeKey(fn) {
    return fn[id] || (fn[id] = ++count);
}