更改js函数参数的引用

时间:2018-11-19 12:12:21

标签: javascript redux functional-programming

最近,我编写了react-redux应用程序,作为React开发人员,我编写了纯净,功能强大且可预测的代码。即使我喜欢这种体验,但我仍然怀疑我的代码是否还不错。

所以我的状态中有一棵树,我需要更新树中的一堆节点。假设树的API提供了方法pureUpdate(path, newNode, tree) => newTree,该方法返回更新了节点的新树。在这种情况下,我的reducer方法可能看起来像

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

但是我不确定是否能做到最好。

看起来很讨厌的第一件事是tree = pureUpdate(path, node, tree);。看起来好像在修改一个参数,不建议这样做,但是我只是在重新分配 参考,不是吗?答案的第二部分对here进行了说明。但是,尽管这种技巧可能没问题,但是in this discussion表示这样的代码可能未经过优化,并且重新分配参数可能会导致性能问题(more info with examples)。对我来说,最简单的解决方法是使用一个额外的变量,该变量将是树的克隆。

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

问题是,如果我什么都不想念,我的代码仍然纯净,美观,不会引起任何问题。

1 个答案:

答案 0 :(得分:3)

如果您完全关心性能,我不会为了避免重新分配参数而克隆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)
  )