为了了解如何使用WeakMap,我提出了以下跟踪函数调用的示例:
var map = new WeakMap();
function countFunctionInvocations(func) {
return function(...args) {
map.set(func, (map.get(func) || 0)+1);
return func.apply(this, args);
}
};
const _add = (x,y) => x+y;
const _inc = x => x+1;
const add = countFunctionInvocations(_add);
const inc = countFunctionInvocations(_inc);
add(2,3);
add(1,2);
add(2,3);
add(2,3);
inc(inc(1));
console.log(map.get(_add), map.get(_inc));
// 4 2
实现这一点的更干净的方法是什么,因为我必须来回地对函数进行别名,例如从add到_add,再到add。另外,上述是否是Weakmap的合法使用?
发布于 2022-05-17 00:04:02
WeakMap的使用非常奇怪--正如您已经注意到的,如果您想用函数查找这些函数,就必须将这些函数存储在变量中,这些变量与计数引用函数是分开的。它使事情变得很尴尬,而且只要您没有函数名冲突,WeakMap似乎就不会比普通对象具有净优势。
如果您所要寻找的内容允许这样做,您可以向countFunctionInvocations传递另一个参数,指示名称,从而允许您传递一个(简洁、匿名)箭头函数。
const counts = {};
function countFunctionInvocations(name, func) {
return function(...args) {
counts[name] = (counts[name] ?? 0) + 1;
console.log("called", name, counts[name]);
return func.apply(this, args);
}
};
const add = countFunctionInvocations('add', (x,y) => x+y);
const inc = countFunctionInvocations('inc', x => x + 1);
add(2,3);
add(1,2);
add(2,3);
add(2,3);
inc(inc(1));
console.log(counts.add, counts.inc);
另外,上述
是否是Weakmap的合法使用?
我的意思是,它可以使用,但正如我们已经注意到的那样--必须有两个单独的引用来引用一个函数,一个是基函数,另一个是countFunctionInvocations转换的函数,这是很尴尬的。
尽管如此,这肯定是WeakMap在地图上的合法使用,因为它允许垃圾收集函数(及其调用计数),而其他任何东西都无法引用它。
我想另一个选项是将返回的函数放到Map中,这样在外部只有一个标识符,但是它需要一个function或第二个参数来指示函数的名称,否则countFunctionInvocations的内部只会看到一个匿名函数而没有名称。
const map = new WeakMap();
function countFunctionInvocations(func) {
const fn = (...args) => {
map.set(fn, (map.get(fn) || 0) + 1); // use returned function in Map
return func.apply(this, args); // invoke passed function
}
return fn;
};
const add = countFunctionInvocations(function add(x, y) { return x + y });
const inc = countFunctionInvocations(function inc(x) { return x + 1 });
add(2,3);
add(1,2);
add(2,3);
add(2,3);
inc(inc(1));
console.log(map.get(add), map.get(inc));
// 4 2
https://stackoverflow.com/questions/72266750
复制相似问题