javascript - 注入(inject)不纯函数与调用它有何不同?

标签 javascript function functional-programming

我正在读一本书,书中说处理不纯函数的一种方法是将它们注入(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/

相关文章:

python - 函数作为参数传递时是否被评估?

映射函数的 C++ 模拟

ruby - 在 Ruby 中乱序柯里化(Currying)

javascript - 2 如何使用 UnderscoreJs 比较 2 个 JSON 的所有属性(除了一个属性)?

javascript - DataTables:总计一列 - 除了具有特定类别的行?

javascript - JavaScript 函数可以返回自身吗?

java - 在java中使用对象函数

haskell - 是否有 `read` 函数的完全替代方案?

javascript - 使用 javascript 查找和替换 href 中的参数

javascript - 在下拉列表中选择新值,同时记住 Jquery 中的旧值