手写函数柯里化示例

今天记录一个经典的手写面试题,手写函数的柯里化示例。

先说一下函数的柯里化是什么样的效果,举个例子,对于计算长方体体积的函数,需要传长、宽、高三个变量,那么可以通过(fun为函数名)

fun(a,b,c)

一次性进行传参,而柯里化过后,便可以分多次进行传参,如:

fun(a,b)(c)
fun(a)(b)(c)

也可以获得相应的结果:

下面是实现的示例代码,这里还是以计算长方体体积的函数来举例:

1.先书写一个基本的,求体积的函数

function mainFun(a,b,c) {
	return a*b*c;
}

2.开始书写构造函数使之转换为柯里化的形式:

先书写一个基本的构造函数,接受的参数便是要转换的函数(mainFun),并在里面存放一个列表用于存放参数(参数):

function klh(fn) {
	let self = this;
	self.canshu = [];
}

ps:此时通过创建一个实例来看到此数组(看一下就行)

let shili = new klh(mainFun);
console.log(shili.canshu);    // []

3.想要让创建出来的实例可以作为函数调用,须在构建函数中return一个函数以供调用传参(即接受长、宽、高),可参考下述代码中的注释(arguments可以获取到该函数接收到的参数)。

function klh(fn) {
	let self = this;
	self.canshu = [];
	return function() {
		console.log('我接收到了参数'+[...arguments].join(','))
        // 输出结果:我接收到了参数2,3
		return [...arguments].join(',');
	}
}
		
let shili = new klh(mainFun);
console.log(shili(2,3))    // 调用return出的函数并输出返回值
// 输出结果:2,3

4.先这里根据接收到的参数分两种情况进行讨论,

第一是接受到的参数已足以计算长方体体积(即已接收到三个参数),此时直接调用示例中的fn函数并返回其返回值即可:

function klh(fn) {
	let self = this;
	self.canshu = [];
	return function() {
        // 存放并记录已经接收过的参
		self.canshu.push(...arguments)
        // 注此处可直接用函数.length获取其参数的长度,mainFun定义时要求接受a、b、c三大变量因此为3
		if(fn.length == self.canshu.length) {
			return fn(...self.canshu)
		}
	}
}
		
let shili = new klh(mainFun);
console.log(shili(2,3,4))
// 输出结果:24

第二种情况就是接受到的参数少于3,后续还会再次调用并传参;此时可将函数自身(可使用arguments.callee直接获取自身)return出去并再次触发并接受参数并push到参数列表(canshu)中:

function klh(fn) {
	let self = this;
	self.canshu = [];
	return function() {
		self.canshu.push(...arguments)
		if(fn.length == self.canshu.length) {
			return fn(...self.canshu)
		} else {
			return arguments.callee;
		}
	}
}
		
let shili = new klh(mainFun);
console.log(shili(2)(3,4))

shili = new klh(mainFun);
console.log(shili(2)(3)(4))	

//两结果均为24

至此便可以完成该需求!

完整代码:

// 函数柯里化

function mainFun(a,b,c) {
	return a*b*c;
}
		
function klh(fn) {
	let self = this;
	self.canshu = [];
	return function() {
		self.canshu.push(...arguments)
		if(fn.length == self.canshu.length) {
			return fn(...self.canshu)
		} else {
			return arguments.callee;
		}
	}
}
		
let shili = new klh(mainFun);
console.log(shili(2)(3,4))
shili = new klh(mainFun);
console.log(shili(2)(3)(4))

希望本文会对您有所帮助~^_^

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值