我正在读一本书,书中说处理不纯函数的一种方法是将它们注入(inject)函数,而不是像下面的示例那样调用它。
普通函数调用:
const getRandomFileName = (fileExtension = "") => {
...
for (let i = 0; i < NAME_LENGTH; i++) {
namePart[i] = getRandomLetter();
}
...
};
注入(inject)然后函数调用:
const getRandomFileName2 = (fileExtension = "", randomLetterFunc = getRandomLetter) => {
const NAME_LENGTH = 12;
let namePart = new Array(NAME_LENGTH);
for (let i = 0; i < NAME_LENGTH; i++) {
namePart[i] = randomLetterFunc();
}
return namePart.join("") + fileExtension;
};
作者说,当我们尝试测试函数时,此类注入(inject)可能会有所帮助,因为我们可以将已知结果的函数传递给原始函数,以获得更可预测的解决方案。
就我所理解的纯函数而言,上述两个函数之间是否存在任何差异,即使在注入(inject)后第二个函数仍然是不纯的?
最佳答案
不纯函数只是包含一个或多个不能从给定输入禁用的副作用的函数。
也就是说,如果它在其范围之外改变数据,并且不会为相同的输入产生可预测的相同输出。
在第一个示例中,NAME_LENGTH
是在函数范围之外定义的 - 因此,如果该值发生变化,getRandomFileName
的行为也会发生变化 - 即使我们提供相同的 fileExtension
每次。同样,getRandomLetter
是在范围之外定义的 - 并且几乎肯定会产生随机输出 - 因此本质上是不纯的。
在第二个示例中,所有内容都在函数范围内被引用或传递给它或在其中定义。这意味着它可以是纯的——但不一定。同样,这是因为某些函数本质上是不纯的 - 因此这取决于 randomLetterFunc
的定义方式。
如果我们调用它
getRandomFileName2('test', () => 'a');
...那么它将是纯粹的——因为每次我们调用它都会得到相同的结果。
另一方面,如果我们调用它
getRandomFileName2(
'test',
() => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.charAt(Math.floor(25 * Math.random()))
);
这是不纯的,因为每次调用它都会得到不同的结果。
关于javascript - 注入(inject)不纯函数与调用它有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73842503/