根据定义, Pure Function 在以下情况下是纯粹的:
所以这是一个纯函数:
function foo(x) {
return x * 2;
}
foo(1) // 2
foo(2) // 4
foo(3) // 6
这也是一个纯函数(在JavaScript上下文中)
Math.floor(x);
Math.floor(1.1); // 1
Math.floor(1.2); // 1
Math.floor(2.2); // 2
问题:如果我们将这两个纯函数结合起来,它仍然会被认为是纯函数吗?
// Nested with Math library
function bar(x) {
return Math.floor(x);
}
// Nested even deeper
function foobar(x) {
return foo(Math.floor(x));
}
显然,在没有副作用的情况下,它仍然总是返回相同的输出相同的输出,但是从其他上下文(范围)调用函数会违反法律#34; 依赖于无外部状态"
答案 0 :(得分:9)
外部状态与外部代码不同。如果纯函数不能使用外部代码,那么根本就没有纯粹的函数。即使你的所有函数都是x * 2
,在(很多)纯函数式语言中,即使*
也是一个函数。所以即使是这个简单的函数也无法避免调用其他函数。
函数定义或多或少只是语法细节。您可以将外部函数的函数体内联到更长的表达式中。 E.g:
function foo(a, b) {
return bar(a) + bar(b);
}
function bar(x) {
return x * 2;
}
与:
相同function foo(a, b) {
return a * 2 + b * 2;
}
唯一的区别是代码片段的可重用性和/或可读性和可维护性。不纯洁。
如果功能不会引起副作用或受到自身外部副作用/状态的影响,则该功能是纯粹的。只要它调用的所有代码也符合该规则,它就会保持纯粹。
答案 1 :(得分:1)
从其他上下文(范围)调用函数是否违反了法律 “不依赖外部状态”?
arguments
和return value
之间的链接仍然是纯粹的。
纯函数将输入(arguments
)映射到输出(return value
),其方式可以仅基于arguments
以100%的准确度进行预测,并且不包含生成return value
所需的任何其他代码。
您可以应用此简单测试来确定它是否纯净:
function multiplication (integer) {
var result = 2 * integer;
return result;
}
console.log(multiplication(4)) // 8
multiplication(integer)
的真实情况是,您的代码中的代码可以简单地用它为给定return value
生成的argument
替换对它的调用。这不是在您的代码中编写multiplication(4)
,而是可以编写8
。一旦函数变得不纯,该测试就会失败:
function multiplicationImpure (integer) {
var result = 2 * integer;
console.log (result);
return result;
}
console.log(multiplicationImpure(4)) // 8 8
现在,如果您在代码中将multiplicationImpure(4)
替换为8
,则它将不再相同:在控制台的输出中将丢失一个8
。同样,如果某个外部状态可能导致参数8
的另一个返回值超过8
,那么简单地将2
放入代码就会出现问题。
答案 2 :(得分:0)
我认为,在JavaScript中,
function foo(x) {
return Math.floor(x);
}
不是纯粹的功能。如果Math
只是名称空间,我会同意。但在JavaScript(AFAIK)中,它是一个功能齐全的可变对象。因此foo
依赖于外部Math
对象的状态而不是纯粹的。使其纯洁的一种方法是使用
const floor = Math.floor();
function foo(x) {
return floor(x);
}
这样,foo
不会取决于Math
对象的状态而且是纯粹的。