Использование WeakMap для отслеживания вызовов функций

Чтобы узнать об использовании 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?

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Сравнение структур данных: Массивы и объекты в Javascript
Сравнение структур данных: Массивы и объекты в Javascript
Итак, вы изучили основы JavaScript и хотите перейти к изучению структур данных. Мотивация для изучения/понимания Структур данных может быть разной,...
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Создание собственной системы электронной коммерции на базе Keystone.js - настройка среды и базовые модели
Прошлая статья была первой из цикла статей о создании системы электронной коммерции с использованием Keystone.js, и она была посвящена главным образом...
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
0
0
17
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование 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);

Additionally, is the above a legitimate usage of Weakmap?

Я имею в виду, что его можно было бы использовать, но, как мы заметили, неудобно иметь две отдельные ссылки на функцию — одна из них является базовой функцией, а другая — преобразованной с помощью countFunctionInvocations.

Тем не менее, это, безусловно, законное использование WeakMap над картой, потому что это позволяет функции (и количеству ее вызовов) собирать мусор, когда ничто другое не может ссылаться на нее.

Я предполагаю, что другим вариантом будет возвращаемая функция, которая будет помещена в карту, чтобы у вас был только один идентификатор снаружи, но для этого потребуется 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

спасибо за все это. Является ли приведенное выше натяжкой для использования типа данных WeakMap? Есть ли для него какое-либо последовательное/законное использование, или оно довольно редко встречается в производственных программах?

David542 17.05.2022 16:25

Раньше это был один из немногих способов для классов иметь хорошую конфиденциальность для свойств экземпляра с помощью замыкания, но теперь это изменилось, когда частные свойства стали опцией. (Она обычно используется в транспилированном коде с Babel). Кроме этого, я никогда не сталкивался с ситуацией, когда писал свой собственный код, где WeakMap казался бы правильным решением, но это отчасти результат моего личного стиля, и я бы не стал этого делать. исключают возможность того, что он никогда не окажется подходящим инструментом для работы в будущем.

CertainPerformance 17.05.2022 17:47

Другие вопросы по теме