我正在重构一些代码,并想知道在递归函数中传递常量时,哪种模式占用内存最少且最容易阅读。
例如,我可以将每个常量传递给下一个递归函数,但这些参数是常量并不明显:
const startFoo = (myArray, isFoo, isBar) => {
console.log(isFoo, isBar);
startFoo(myArray, isFoo, isBar);
};
或者,我可以有2个函数并在第一个函数的闭包中保持常量,但我很好奇,如果每次调用第一个函数时重新创建第二个函数将导致不必要的对象创建& GC:
const startFoo = (myArray, isFoo, isBar) => {
const foo = myArray => {
console.log(isFoo, isBar);
foo(myArray);
};
foo(myArray);
};
最后,我可以将它保留在一个函数中,只缓存初始值:
const startFoo = (myArray, isFoo, isBar) => {
if (!startFoo.cache) {
startFoo.cache = {
isFoo,
isBar
}
}
const {isFoo, isBar} = startFoo.cache;
console.log(isFoo, isBar);
startFoo(myArray);
};
所有3看起来他们都会成为即将到来的(这里是)TCO的好候选人,所以我不认为这会影响决定,但是如果确实这样做也很好知道!
答案 0 :(得分:4)
这些参数是常数
并不明显
那么重要吗?如果您因为喜欢函数式方法而选择循环递归,那么所有变量和参数都是常量。通过查看递归调用并将参数与函数的参数进行比较,可以判断它们是否在递归下降中保持不变。
或者,我可以有2个函数并保持常量在第一个的闭包中,但我很好奇,如果每次调用第一个函数时重新创建第二个函数将导致不必要的对象创建& GC
不太可能。 Afaik,没有函数对象被实例化为简单的内联辅助函数,它们从不用作对象或导出为闭包。至少它是一个相当简单的优化,即使没有完成,GC压力也不会很难或显着损害性能。
你应该采用这种方法,因为它是最干净,最易维护的。
我可以将它保留在一个函数中,只需缓存初始值
你最好不要那样做。它在函数中引入了一个额外的条件,它将影响性能,因为它在每次调用时都会执行,但最重要的是它会使代码复杂化不必要。这也可能是您引入错误的原因 - 您永远不会在基本情况 1 中取消设置.cache
,这样所有调用都将使用相同的常量,无论传递给它们的是什么。此外,您将常量泄漏到全局范围,任何人都可以访问它们。
1:不可否认,你的演示功能没有一个基本情况,但问问自己:如果你添加了一个,你会忘记取消设置缓存吗?