首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用WeakMap跟踪函数调用

使用WeakMap跟踪函数调用
EN

Stack Overflow用户
提问于 2022-05-16 23:49:48
回答 1查看 24关注 0票数 0

为了了解如何使用WeakMap,我提出了以下跟踪函数调用的示例:

代码语言:javascript
复制
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的合法使用?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-17 00:04:02

WeakMap的使用非常奇怪--正如您已经注意到的,如果您想用函数查找这些函数,就必须将这些函数存储在变量中,这些变量与计数引用函数是分开的。它使事情变得很尴尬,而且只要您没有函数名冲突,WeakMap似乎就不会比普通对象具有净优势。

如果您所要寻找的内容允许这样做,您可以向countFunctionInvocations传递另一个参数,指示名称,从而允许您传递一个(简洁、匿名)箭头函数。

代码语言:javascript
复制
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的内部只会看到一个匿名函数而没有名称。

代码语言:javascript
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72266750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档