Изменение ссылки на аргумент функции js - PullRequest
0 голосов
/ 19 ноября 2018

В последнее время я пишу приложения на основе реакции-редукса, а как разработчик реагирования пишу чистый, функциональный и предсказуемый код.Несмотря на то, что мне нравится этот опыт, у меня есть сомнения, хорош ли мой код или нет.

Итак, у меня есть дерево в моем состоянии, и мне нужно обновить группу узлов в дереве.Скажем, API дерева предоставляет pure метод pureUpdate(path, newNode, tree) => newTree, который возвращает новое дерево с обновленным узлом.В этом случае мой метод редуктора может выглядеть следующим образом:

function updateNodes(tree, updateRules) {
    updateRules.forEach(updateRule => {
        const { path, node } = updateRule;
        tree = pureUpdate(path, node, tree);
    });
    return tree;
}

Но я не уверен, что это лучшее, что можно сделать.

Первое, что выглядит противно, это tree = pureUpdate(path, node, tree);.Это похоже на изменение параметра, что не рекомендуется, но я просто переназначаю ссылку, не так ли?Это объяснено здесь во второй части ответа.Но хотя этот трюк мог бы подойти, в этом обсуждении сказал, что такой код может быть неоптимизирован, и переназначение параметров может вызвать проблемы с производительностью ( больше информации с примерами ).Самое простое решение, которое мне пришло в голову, - это использовать дополнительную переменную, которая будет клоном дерева.

function updateNodes(tree, updateRules) {
    let newTree = someCloneFunc(tree);
    updateRules.forEach(updateRule => {
        const { path, node } = updateRule;
        newTree = pureUpdate(path, node, newTree);
    });
    return newTree;
}

Вопрос в том, не пропущу ли я что-нибудь, и мой код все еще чистый, красивый и будетне вызывает никаких проблем.

1 Ответ

0 голосов
/ 19 ноября 2018

Если вас вообще беспокоит производительность, я бы не стал клонировать tree, чтобы просто не переназначить параметр.

Хотя вы можете использовать forEach здесь и переназначить параметр, reduce - это правильная функциональная абстракция для вашего случая использования, и, как правило, она лучше и полезнее, чем forEach, поскольку она может (и должна) быть используется чисто, тогда как forEach всегда о побочных эффектах.

Решение, основанное на reduce, также ставит вопрос о том, стоит или нет полностью клонировать или переназначить параметр функции.

Вот рабочее решение reduce - нет переназначения параметров, нет forEach побочных эффектов и нет причин клонировать tree:

const updateNodes = (tree, updateRules) =>
  updateRules.reduce(
    (acc, { path, node }) => pureUpdate(path, node, acc),
    tree // initialize acc (the accumulator)
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...