纯函数

说明

image.png
image.png
image.png
image.png
意思是调用的函数不依赖外部的变量,比如调用foo(111) ,不管在哪里调用,return出来的都是一样的,而不是根据外部环境不一样导致不一样。

image.png
副作用见下,就是不能对外部产生影响

image.png

副作用

image.png
image.png

案例

  1. var names = ["abc", "cba", "nba", "dna"]
  2. // slice只要给它传入一个start/end, 那么对于同一个数组来说, 它会给我们返回确定的值
  3. // slice函数本身它是不会修改原来的数组
  4. // slice函数本身就是一个纯函数
  5. var newNames1 = names.slice(0, 3)
  6. console.log(newNames1)
  7. console.log(names)
  8. // ["abc", "cba", "nba", "dna"]
  9. // splice在执行时, 有修改掉调用的数组对象本身, 修改的这个操作就是产生的副作用
  10. // splice不是一个纯函数
  11. var newNames2 = names.splice(2)
  12. console.log(newNames2)
  13. console.log(names)

修改对象属性,只能通过返回新对象的方式,不影响原对象
image.png

优势

image.png
image.png
image.png

===================

柯理化

说明

image.png
image.png

  1. // 柯里化
  2. // 只传递 toUpOrLow() 这个函数的1个参数upOrLow来调用它,
  3. // 然后它返回另一个函数,来处理剩余参数str
  4. function toUpOrLow(upOrLow){
  5. if(upOrLow == "up"){
  6. return function(str){
  7. return str.toUpperCase()
  8. }
  9. }else if(upOrLow == "low"){
  10. return function(str){
  11. return str.toLowerCase()
  12. }
  13. }
  14. }
  15. console.log(toUpOrLow("up")("aBc")) // "ABC"
  16. console.log(toUpOrLow("low")("aBc")) // "abc"

image.png 某些情况可以通过箭头函数简化 image.png

作用1:函数的职责单一

image.png

作用2:复用

image.png

image.png
image.png

转成柯理化

  1. // 普通函数
  2. function log(date, type, message) {
  3. console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]: [${message}]`)
  4. }
  5. // 柯里化函数的实现hyCurrying
  6. function hyCurrying(fn) {
  7. function curried(...args) {
  8. // 判断当前已经接收的参数的个数, 可以参数本身需要接受的参数是否已经一致了
  9. // 1.当已经传入的参数 大于等于 需要的参数时, 就执行函数
  10. if (args.length >= fn.length) {
  11. // fn(...args)
  12. // fn.call(this, ...args)
  13. return fn.apply(this, args)
  14. } else {
  15. // 没有达到个数时, 需要返回一个新的函数, 继续来接收的参数
  16. function curried2(...args2) {
  17. // 接收到参数后, 需要递归调用curried来检查函数的个数是否达到
  18. return curried.apply(this, args.concat(args2))
  19. }
  20. return curried2
  21. }
  22. }
  23. return curried
  24. }
  25. // 普通函数,转成柯理化
  26. var curryAdd = hyCurrying(add1)
  27. console.log(curryAdd(10, 20, 30))
  28. console.log(curryAdd(10, 20)(30))
  29. console.log(curryAdd(10)(20)(30))

使用场景

Vue源码,很多高级的库里面有用到,可以自己定制化一些实现(比如自定义渲染器),然后传入柯理化的函数,增加可拓展性

===================

组合函数

说明

image.png
image.png 两个函数
image.png 正常调用
image.png组合调用

通用的组合函数

  1. function fnCompose(...fns) {
  2. // 获取传入函数的数量
  3. var length = fns.length
  4. // 1、先判断传入的是不是函数
  5. for (var i = 0; i < length; i++) {
  6. if (typeof fns[i] !== 'function') {
  7. throw new TypeError("Expected arguments are functions")
  8. }
  9. }
  10. // 定义组合函数
  11. function compose(...args) {
  12. var index = 0
  13. // 调用第一个函数
  14. var result = length ? fns[index].apply(this, args): args
  15. // 如果还有其他函数,就依次调用
  16. while(++index < length) {
  17. result = fns[index].call(this, result)
  18. }
  19. return result
  20. }
  21. // 最后返回出去调用
  22. return compose
  23. }