理解js函数柯里化

函数柯里化

用过loadsh的都大概了解过其中提供了一个curry方法,可以把传参拆分开延迟执行;把简单函数复杂化,复杂化是为了通用性,为了能够更灵活调用,重复使用。
比如:

function num(a, b, c) {
	console.log(a,b,c)
}

这个函数经过柯里化后

const curryNum = curry(num);

可以分开传参

curryNum(1)(2)(3);
curryNum(1)(2, 3);
curryNum(1, 3)(3);
// 或者
const curryNums = curryNum(1);
curryNums(2)(3);

等等操作

简单来说就是相当于抽离出复用的函数来便于后面再复用,举个栗子。
封装正则校验函数以便于复用

function checkByReg(reg, data) {
	return reg.test(data)
}
const checkMobile = checkByReg(/^1\d{10}$/, '13302909105');
const checkMobile1 = checkByReg(/^1\d{10}$/, '12345678901');
const checkMail = checkByReg(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/, '123@outlook.com');

…等等

是不是发现这样写很不cooooooooool,感觉还可以再封装一遍抽离相同的正则再传参校验。
如果使用柯里化的话,是不是可以更灵活?

const curryCheck = curry(checkByReg);
const checkMobile = curryCheck(/^1\d{10}$/);
const checkMail = curryCheck(/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/);

checkMobile('13302909105');
checkMail('123@outlook.com');

那么 这个curry方法是怎么实现的呢?
下面来一个简易版的柯里化函数

/**
 * fn 需要柯里化的函数
 * len fn的形参个数
 * args 传入的形参
 */
function _curry(fn, len, ...args) {
	// 利用闭包特性接收传入参数
	/** 
	 * params 拆分传入的参数
	 */
	return function(...params) {
		// 已收集到的参数
		const _args = [...args, ...params];
		// 当收集的参数已经跟函数的参数个数一致时返回该函数并将所有参数传进来
		if (_args.length >= len) {
			return fn.call(this, ..._args)
		} else {
			// 没有收集完则继续递归
			return _curry(fn, len, ..._args)
		}
	}
}
/**
 * 将函数柯里化
 * @param fn    待柯里化的原函数
 * @param len   所需的参数个数,默认为原函数的形参个数
 */
function curry(fn, len = fn.length) {
	return _curry.call(this, fn, len)
}

此时柯里化函数完成了,回到开头,调用柯里化num函数

const curryNum = curry(num);

curryNum(1)(2)(3); // 1,2,3
curryNum(1)(2, 3); // 1,2,3

可以看出来 js里函数柯里化实则是利用闭包和递归去收集每次传入的参数,直到实参个数和形参个数一致时返回并传入全部参数;

… end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值