Javascript 函数式编程和闭包/部分应用

Javascript 函数式编程和闭包/部分应用,javascript,functional-programming,closures,Javascript,Functional Programming,Closures,我对函数式编程的本质感到困惑。需要指出的是,高阶函数是关键概念之一,它支持闭包和部分应用等技术,即在返回函数的同时捕获状态或策略 然而,另一个关键概念是纯函数和不可变状态。换句话说,函数不会有副作用,也不会读取外部状态。它们应始终返回具有相同参数的相同结果 这似乎与高阶函数的概念相矛盾,在高阶函数中,函数确实可以访问闭包封装的状态。当然,这并不意味着函数必须改变状态,但至少状态会影响它的行为 换句话说,相同的函数可能会在程序的后续执行中返回不同的结果。还是我误解了,同一个概念意味着什么?我想到的

我对函数式编程的本质感到困惑。需要指出的是,高阶函数是关键概念之一,它支持闭包和部分应用等技术,即在返回函数的同时捕获状态策略

然而,另一个关键概念是纯函数不可变状态。换句话说,函数不会有副作用,也不会读取外部状态。它们应始终返回具有相同参数的相同结果

这似乎与高阶函数的概念相矛盾,在高阶函数中,函数确实可以访问闭包封装的状态。当然,这并不意味着函数必须改变状态,但至少状态会影响它的行为

换句话说,相同的函数可能会在程序的后续执行中返回不同的结果。还是我误解了,同一个概念意味着什么?我想到的是一个同名函数和一个体,闭包与否。毕竟,我们谈论的是类似数学的函数,而不是唯一实体的方法。我是否应该将高阶函数返回的函数视为不同的函数,而不仅仅是引用函数,而是定义函数?

来源:

在计算机编程中,如果以下两种关于函数的语句都成立,则函数可以被视为纯函数:

给定相同的参数值,该函数始终计算相同的结果值。函数结果值不能依赖于任何隐藏信息或状态,这些信息或状态在程序执行过程中或程序不同执行之间可能发生变化,也不能依赖于来自I/O设备的任何外部输入(通常见下文)

对结果的评估不会导致任何语义上可观察到的副作用或输出,例如可变对象的突变或I/O设备的输出(通常见下文)

所以纯度是由函数的行为定义的,如果函数的行为使得结果保持不变,即使它依赖于一些封装的内部状态,那么函数将是纯的

此函数不是纯粹的,因为它的返回值(恰好是一个函数)在相同的调用中不同:

function x() {                   // Not Pure because return value depends on external effect.
    const x = Math.random();
    return () => x;             // Pure
}
同样地:

function x() {
    let x = 0
    return {
        fn1(y) {           // Not pure 
            x = x + y      // side effect which is observable through fn2
            return x
        },
        fn2() {            // Not pure because outcome depends on external environment besides arguments
            return x       // x is exposed to outside world through fn1
        }
    }
}
因此,杂质具有传染性。将状态暴露于外界突变的不纯函数会使依赖于同一状态的任何其他函数变得不纯

相比之下,以下为纯函数(假设expensiveComputation函数为纯函数):

这一个也是:

function fn(x) {           // Pure
    return {
        next() {
          return x + 1;
       }
       prev() {
         return x - 1;
       }
   }
}

y = fn(x)
y.next() // Pure 
y.prev() // Pure
发件人:

在计算机编程中,如果以下两种关于函数的语句都成立,则函数可以被视为纯函数:

给定相同的参数值,该函数始终计算相同的结果值。函数结果值不能依赖于任何隐藏信息或状态,这些信息或状态在程序执行过程中或程序不同执行之间可能发生变化,也不能依赖于来自I/O设备的任何外部输入(通常见下文)

对结果的评估不会导致任何语义上可观察到的副作用或输出,例如可变对象的突变或I/O设备的输出(通常见下文)

所以纯度是由函数的行为定义的,如果函数的行为使得结果保持不变,即使它依赖于一些封装的内部状态,那么函数将是纯的

此函数不是纯粹的,因为它的返回值(恰好是一个函数)在相同的调用中不同:

function x() {                   // Not Pure because return value depends on external effect.
    const x = Math.random();
    return () => x;             // Pure
}
同样地:

function x() {
    let x = 0
    return {
        fn1(y) {           // Not pure 
            x = x + y      // side effect which is observable through fn2
            return x
        },
        fn2() {            // Not pure because outcome depends on external environment besides arguments
            return x       // x is exposed to outside world through fn1
        }
    }
}
因此,杂质具有传染性。将状态暴露于外界突变的不纯函数会使依赖于同一状态的任何其他函数变得不纯

相比之下,以下为纯函数(假设expensiveComputation函数为纯函数):

这一个也是:

function fn(x) {           // Pure
    return {
        next() {
          return x + 1;
       }
       prev() {
         return x - 1;
       }
   }
}

y = fn(x)
y.next() // Pure 
y.prev() // Pure

在随后执行程序时,它可能不会返回不同的结果

function adder(init) {
  return (arg) => init + arg;
}    
这将返回一个函数。它每次都返回一个不同的函数,但使用相同的参数返回一个与使用相同参数的前一个函数完全相同的函数。这使它变得纯洁

const add10 = adder(10);
const add20 = adder(29);
add10
add20
不同的功能。它们运行相同的代码,但闭包不同。它们都是纯的,因为它们的返回值仅依赖于它们的输入


变异的闭包通常很容易从代码中看到,但变异的全局闭包更难看到。我曾经有过几次在加载库时,
Object
发生了变异,而且前后的结果并不总是相同的。函数的纯度依赖于自由变量,全局变量是自由变量中最脆弱的

在随后执行程序时,它可能不会返回不同的结果

function adder(init) {
  return (arg) => init + arg;
}    
这将返回一个函数。它每次都返回一个不同的函数,但使用相同的参数返回一个与使用相同参数的前一个函数完全相同的函数。这使它变得纯洁

const add10 = adder(10);
const add20 = adder(29);
add10
add20
不同的功能。它们运行相同的代码,但闭包不同。它们都是纯的,因为它们的返回值仅依赖于它们的输入

变异的闭包通常很容易从代码中看到,但变异的全局闭包更难看到。我曾经有过几次在加载库时,
Object
发生了变异,而且前后的结果并不总是相同的。函数的纯度依赖于自由变量,全局变量是自由变量中最脆弱的

利用闭包