重学js 第二篇, 函数式编程

1、什么是函数式编程

  1. 函数式编程,指的是 函数 数学中的 映射关系,并不是单纯的指函数本身
  2. 纯函数,指的是 多次 输入和输出 一致的函数
  3. 有副作用的函数 指的是 依赖外部变量的 函数,因为 内部的 执行结果 就变成了 不可控的
let arr = [1, 2, 3, 4, 5, 6, 7]

// 如下 slice 就是纯函数
arr.slice(0, 3) // [1, 2, 3]
arr.slice(0, 3) // [1, 2, 3]
arr.slice(0, 3) // [1, 2, 3]
arr.slice(0, 3) // [1, 2, 3]

// splice 就不是纯函数
arr.splice(0, 3) // [1, 2, 3]
arr.splice(0, 3) // [4, 5, 6]
arr.splice(0, 3) // [7]

函数式编程中比较 值得记录的点

1、缓存

因为纯函数 是多次输入和输出一致的函数,所以可以使用 对象把结果缓存起来

 算法题中 著名 的 斐波那契 数列 就可以使用 缓存来进行 优化回调的问题

function memorize(fn) {
   const cache = {}
   return function () {
      const key = JSON.stringify(arguments)
      cache[key] = cache[key] || fn(...arguments)
      return cache[key]
   }
}

2.柯里化

柯里化 巧妙地利用了 函数 一等公民 以及 闭包 的 特点

function curry (fn) {
  const curried = (...args) => (args.length === fn.length) ?
          fn(...args) : (..._args) => curried(...args, ..._args)
  return curried
}

柯里化 的 具体实现我就不讲了,但是可以说一个 之前就在使用的实际应用场景

在 前端 和 后端 交互的过程中,会出现很多的枚举值,但是大多数人 都是 使用 if else 完事

但是我们可以把枚举值 都提取出来,如下所示

export const saleStatus = {
  '停售': 1,
  '已售罄': 2,
  '待售': 3,
  '发售中': 4
}

然后使用一个函数,将这个枚举值 作为 可以 符合 习惯,用 ‘1’ 这样的值读取的新函数

export const commonJudgeType = (enums, default_value = '--') => (status) => {
  for (const key in enums) {
    if (enums.hasOwnProperty(key)) {
      const st = enums[key];
      if (typeof st === 'object') {
        if (st.code === parseInt(status)) return key
      } else {
        if (st == status) return key
      }
    }
  }
  return default_value
}

export const judgeSale = commonJudgeType(saleStatus, '已售罄')

这里返回了一个新的函数,同时 对传入的 saleStatus 形成了一个闭包。

这样使用 judgeSale 就可以轻易地 将对应的值给读出来了

3、函数组合

在前面的文章中,以及网络上的很多资料里,都有介绍过 redux 中的 compose 函数,

使用这个函数 可以 把 一个函数的颗粒化变小,然后组合成为 一个复杂的函数

 function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }
 
  if (funcs.length === 1) {
    return funcs[0]
  }
 
  // 每个函数的返回值 都会被 当做 一个
  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
function reverse(arr) {
  return arr.reverse()
}
function join(j) {
  return function(arr) {
    return return arr.join(j)
  }
}
function splite(s) {
  return function (str) {
    return str.split(s)
  }
}

如上面3 个函数

compose(join('-'), reverse, splite(' '))('hello world')
//  输出的结果 就是 
//  "world-hello"

4. 函子对象

每一个函子 都是一个 盒子,包含了 当前传入的值,不直接操作值。

所有的 操作 由函子完成,map 返回的是 一个包含新之的盒子

所以这个是 支持 链式调用

// 函子对象
class Container{
  static of (value) {
     return new Container(value)
  }
  // 对函数进行处理
  map(fn) {
    return Container.of(fn(this._value))
  }
  constructor(value) {
    this._value = value
  }
   join() {
     this._value
   }
}

5、正则表达式

这个 完全是抄来的,对于正则表达式 十窍通了九窍

/(\d{4})(\d{2})(\d{2})/.exec('20204040')

/(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})/.exec('20204040')

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值