6.JavaScript柯里化

2021-09-17  本文已影响0人  静昕妈妈芦培培

柯里化也是属于函数式编程里面一个非常重要的概念。

我们先来看一下维基百科的解释:
维基百科的结束非常的抽象,我们这里做一个总结:

柯里化的结构

//下面把add函数转换为sum函数的过程就叫柯里化
function add(x, y, z) {
  return x + y + z;
}
var result = add(10, 20, 30);
console.log(result); //60

//把add函数进行柯里化
function sum(x) {
  return function (y) {
    return function (z) {
      return x + y + y;
    };
  };
}
var result1 = sum(10)(20)(30);
console.log(result1);


//简化柯里化的代码
var sum2 = x => y => z => x + y + z

柯里化的作用

1.让函数的职责单一

那么为什么需要有柯里化呢?

比如上面的案例我们进行一个修改:传入的函数需要分别被进行如下处理
function add(x, y, z) {
  x = x + 2;
  y = y * 2;
  z = z ** 2;
  return x + y + z;
}
console.log(add(10, 20, 30));
function sum(x) {
  x = x + 2;
  return function (y) {
    y = y * 2;
    return function (x) {
      z = z ** 2;
      return x + y + z;
    };
  };
}
console.log(sum(10)(20)(30));

2.柯里化的复用

另外一个使用柯里化的场景是可以帮助我们可以复用参数逻辑:

function sum(num1, num2) {
  return num1 + num2
}
//如果需要多次把一个数字和5相加,求值
sum(5, 10)
sum(5, 15)
sum(5, 88)
sum(5, 120)
//使用柯里化
function makeAdder(count) {
  return function(num) {
    return count + num
  }
}

var add5 = makeAdder(5)//这一段逻辑被复用
add5(10)
add5(15)
add5(88)
add5(120)

3.打印日志的柯里化

这里我们在演示一个案例,需求是打印一些日志:

//打印日志的柯里化
function log(date, type, message) {
  console.log(`[${date.getHours()}:${date.getMinutes()}]:[${type}]:[${message}]`)
}

//每次都需要输入时间,类型,信息,即使时间一样
log(new Date(), "DEBUG", "查询轮播图的bug")
log(new Date(), "DEBUG", "查询菜单的bug")
log(new Date(), "DEBUG", "查询列表的bug")
var log1 = date => type => message => {
  console.log(`[${date.getHours()}:${date.getMinutes()}]:[${type}]:[${message}]`)
}
//如果我现在打印的都是当前时间,
var nowLog = log1(new Date())
//只需要输入类型和信息
nowLog("DEBUG", "查询轮播图的bug")
nowLog("FETURE", "添加了新用户功能")
nowLog("FIX", "修复了菜单问题")

//如果我现在打印的都是当前时间的bug
var nowDebugLog = log1(new Date())("DEBUG")
//只需要输入信息
nowDebugLog("查询轮播图的bug")
nowDebugLog("查询菜单的bug")
nowDebugLog("查询列表的bug")

自动柯里化函数

需求:传入一个普通函数,返回一个新的函数,是传入的函数的柯里化函数

function curry(fn) {
  
}

//满足下面功能
function add(x, y, z) {
  return x + y + z;
}

const curryAdd = curry(add);
console.log(curryAdd(10, 20, 30)); //60
console.log(curryAdd(10, 20)(30)); //60
console.log(curryAdd(10)(20, 30)); //60
console.log(curryAdd(10)(20)(30)); //60

实现

//需求:传入一个普通函数,返回一个新的函数,是传入的函数的柯里化函数
function curry(fn) {
  return function proxy(...args) {
    //通过fn.length获取到fn的形参个数
    //假如传给proxy函数的实参个数大于等于fn的形参个数,说明已经传入了所有的参数

    if (args.length >= fn.length) {
      //直接调用fn即可,但需要保证proxy函数上下文的this和fn的this保持一致,并返回执行结果
      return fn.apply(this, args);
    } else {
      return function proxy2(...params) {
        return proxy.call(this, ...args.concat(params));
      };
    }
  };
}

非常感谢王红元老师的深入JavaScript高级语法让我学习到很多 JavaScript 的知识

上一篇 下一篇

猜你喜欢

热点阅读