概念

函数式编程是一种编程范式,主要是利用函数把运算过程封装起来,通过组合各种函数来处理数据,通过串联多个函数来计算,类似一条流水线。

特点

函数是一等公民

函数与其他数据类型一样,处于平等地位,可以赋值给变量,可以作为函数入参或者返回值。

  1. ajaxCall(json => callback(json)); // 脱裤子放P
  2. // 等价于这行
  3. ajaxCall(callback);

高阶函数: 把函数作为参数或者返回值的一类函数。

声明式编程

声明式编程关心做什么,命令式编程关心怎么做

  1. // 命令式
  2. var makes = [];
  3. for (i = 0; i < cars.length; i++) {
  4. makes.push(cars[i].make);
  5. }
  6. // 声明式
  7. var makes = cars.map(function(car){ return car.make; });

纯函数

  • 无状态:函数的输出仅取决于输入,而不依赖外部状态;
  • 无副作用: 不修改外部状态,不修改入参。

意味着相同的输入,永远会得到相同的输出

  1. var xs = [1,2,3,4,5];
  2. // 纯的
  3. xs.slice(0,3);
  4. //=> [1,2,3]
  5. // 不纯的
  6. xs.splice(0,3); //改变原数组
  7. //=> [1,2,3]

其他优点:

  • 可缓存性,因为相同的输入得会得到相同的输出,那么可以缓存函数的结果。
  • 可移植性/自文档化,纯函数的依赖很明确,因此更易于观察和理解
  • 可测试性,函数让测试更加简单,只需简单地给函数一个输入,然后断言输出就可以了。
  • 引用透明性,如果一段代码可以替换成它执行所得的结果,而且是在不改变整个程序行为的前提下替换的,那么我们就说这段代码是引用透明的。

    柯里化(curry)

    柯里化的意思是将一个多元函数,转换成一个依次调用的单元函数
    1. f(a,b,c) f(a)(b)(c)
    柯里化函数会接收一些参数,然后不会立即求值,而是继续返回一个新函数,将传入的参数通过闭包的形式保存,等到被真正求值的时候,,再进行求值。 ```javascript var add = function(x) { return function(y) { return x + y; }; }; const increment = add(1);

increment(10); // 11

  1. <a name="cxOSF"></a>
  2. ### 偏函数
  3. > **偏函数** ( Partial )是指固定一个函数的一些参数,然后产生另一个更小元的函数。
  4. > In computer science, partial application(or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity.
  5. - 柯里化:将多参数函数转换成多个单参数函数,也就是将一个 n 元函数转换成 n 个一元函数
  6. - 偏函数:则是固定一个函数的一个或多个参数,也就是将一个 n 元函数转换成一个 n - x 元函数
  7. ```javascript
  8. // 柯里化
  9. f(a,b,c) → f(a)(b)(c)
  10. // 偏函数
  11. f(a,b,c) → f(a)(b,c) / f(a,b)(c)

组合(compose)

函数组合的目的是将多个函数组合成一个函数

  1. const compose = (f, g) => x => f(g(x))
  2. const f = x => x + 1;
  3. const g = x => x * 2;
  4. const fg = compose(f, g);
  5. fg(1) //3
  1. function compose(...fns) {
  2. return fns.reduce((a,b) => {
  3. return (...args) => {
  4. return a(b(...args))
  5. }
  6. })
  7. }
  8. function fn1(a) {
  9. console.log('fn1: ', a);
  10. return a+1
  11. }
  12. function fn2(a) {
  13. console.log('fn2: ', a);
  14. return a+1
  15. }
  16. function fn3(a) {
  17. console.log('fn3: ', a);
  18. return a+1
  19. }
  20. console.log(compose(fn1, fn2, fn3)(1));

参考

简明 JavaScript 函数式编程——入门篇—网易云
浅析JavaScript函数式编程—转转
《函数式编程指北》中文翻译
https://juejin.cn/post/6844903909169823751