大多数源将纯函数定义为具有以下两个属性:
这是与我有关的第一个条件。在大多数情况下,很容易判断。考虑以下JavaScript函数(如本文所示)
纯:
const add = (x, y) => x + y;
add(2, 4); // 6
Run Code Online (Sandbox Code Playgroud)
不纯:
let x = 2;
const add = (y) => {
return x += y;
};
add(4); // x === 6 (the first time)
add(4); // x === 10 (the second time)
Run Code Online (Sandbox Code Playgroud)
不难看出,第二个函数将为后续调用提供不同的输出,从而违反了第一个条件。因此,这是不纯的。
这部分我明白了。
现在,对于我的问题,考虑以下函数,该函数将给定的美元金额转换为欧元:
(编辑- const在第一行中使用。let较早地使用。)
const exchangeRate = fetchFromDatabase(); // evaluates to say 0.9 for today;
const dollarToEuro = (x) => {
return …Run Code Online (Sandbox Code Playgroud) 我是函数式编程的新手,我正在尝试重写一些代码,以使其更具功能性以掌握概念。刚才我发现了Array.reduce()函数并用它来创建一个组合数组的对象(我之前使用过for循环)。但是,我不确定某些事情。看看这段代码:
const sortedCombinations = combinations.reduce(
(accum, comb) => {
if(accum[comb.strength]) {
accum[comb.strength].push(comb);
} else {
accum[comb.strength] = [comb];
}
return accum;
},
{}
);
Run Code Online (Sandbox Code Playgroud)
显然,这个函数改变了它的参数accum,所以它不被认为是纯的。另一方面,如果我理解正确,reduce 函数会在每次迭代中丢弃累加器,并且在调用回调函数后不使用它。尽管如此,它不是一个纯函数。我可以像这样重写它:
const sortedCombinations = combinations.reduce(
(accum, comb) => {
const tempAccum = Object.assign({}, accum);
if(tempAccum[comb.strength]) {
tempAccum[comb.strength].push(comb);
} else {
tempAccum[comb.strength] = [comb];
}
return tempAccum;
},
{}
);
Run Code Online (Sandbox Code Playgroud)
现在,在我的理解中,这个函数被认为是纯函数。但是,它每次迭代都会创建一个新对象,这会消耗一些时间,显然还消耗内存。
所以问题是:哪个变体更好,为什么?纯度真的那么重要以至于我应该牺牲性能和内存来实现它吗?或者也许我遗漏了一些东西,有更好的选择吗?