函数的柯里化

本文深入探讨了JavaScript中的柯里化(Currying)概念,通过实例展示了如何将函数转换为接受部分参数并返回新函数的形式,以实现参数分解和逻辑复用。此外,还介绍了函数组合(Composition)的概念,如何将多个函数串联执行以简化代码。文章最后提出了一个需求,即创建一个能自动将函数柯里化的通用函数,并给出了其实现。柯里化和函数组合在提高代码可读性和模块化方面具有重要意义。
摘要由CSDN通过智能技术生成

在函数式编程中柯里化是一个十分重要的概念

那么 什么是柯里化呢?

定义:

只传递给函数一部分参数来调用它,让它返回一个函数去处理剩余的参数。这个过程就叫做柯里化。

实例:

// 未柯里化的函数
function add1(x,y,z){
	return x+y+z
}
console.log(add1(10,20,30))

// 柯里化处理的函数
function add2(x){
	return function(y){
		return function(z){
			return x+y+z
		}
	}
}
// 可以化处理的函数可以简化成
// var sum2 = x=>y=>z=>x+y+z
console.log(add2(10)(20)(30))

光从上面的例子来看的话,就会觉得函数的柯里化没有必要,
反而更加复杂化了,但其实不是这样。

在函数式编程中,我们往往希望一个函数处理的问题尽可能的单一,而不是将一大堆的处理过程都交给一个函数来处理。

那么我们就可以将每次传入的参数在单一的函数中进行处理,处理完后在下一个函数中再使用处理后的结果。

比如我们那上面的案例进行一个修改:传入的函数分别需要进行如下的处理

  • 第一个参数+2
  • 第二个参数*2
  • 第三个参数**2
function addx(x){
	x=x+2
	return function(y){
		y=y*2
		return function(z){
			z=z**2
			return x+y+z
		}
	}
}

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

makeAdder函数要求我们传入一个num(当我们需要的时候,可以对num进行一些修改)

function makeAdder(num){
	return function(count){
		return num+count
	}
}

var add5 = makeAdder(5)
add5(10)
add5(100)

var add10 = makeAdder(10)
add10(10)
add10(100)

在这里我们演示一个案例 需求是打印一些日志
(包括时间,类型,信息)

// 普通函数的实现方式
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 log = date => type => message => {
  console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]: [${message}]`)
}

// 如果我现在打印的都是当前时间
var nowLog = log(new Date())
nowLog("DEBUG")("查找到轮播图的bug")
nowLog("FETURE")("新增了添加用户的功能")

var nowAndDebugLog = log(new Date())("DEBUG")
nowAndDebugLog("查找到轮播图的bug")
nowAndDebugLog("查找到轮播图的bug")
nowAndDebugLog("查找到轮播图的bug")
nowAndDebugLog("查找到轮播图的bug")


var nowAndFetureLog = log(new Date())("FETURE")
nowAndFetureLog("添加新功能~")

相信通过上面的总结 大家应该对函数的柯里化的重要性有了一定的认识

那么现在我们在提一个新的需求——我们现在需要一个函数,这个函数能够将我们传入的函数自动生成柯里化函数,不需要我们自己再写一个新的函数

// 柯里化函数的实现
function newCurry(fn){
	function curried(...args){
		// 判断当前已经接收的参数的个数,与参数fn本身需要接受的参数是否一致
		// 当已经传入的参数 大于等于 需要的参数的时候,就执行函数
		if(args.length >= fn.length){
			return fn.call(this,...args)
		}else{
			// 当已经传入的参数没有达到fn的参数个数的时候,需要返回一个函数继续来接收参数
			return curried2(...args2){
				// 接收完参数后,需要递归调用curried来检查个数是否已经一致了
				return curried.call(this,args.concat(args2))
			}
		}
	}
	return curried
}

理解组合函数

组合函数是在js开发过程中的一种对函数的技巧、模式

比如我们现在需要对某一个数据进行函数的调用,执行两个函数fn1和fn2,这两个函数是依次执行的
如果我们每一次都需要对两个函数进行调用,操作上就会显得重复
所以我们可以将两个函数组合起来,自动依次调用
这个过程就是对函数的组合,我们称为组合函数

function double(num){
	return num*2
}

function square(num){
	return num**2
}

function compose(fn1,fn2){
	return function(x){
		return fn2(fn1(x))
	}
}

var calcFn = compose(double,square)
console.log(calcFn(10))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值