对函数式编程弄得不是很清楚,所以想请假一下下面这两种方法在实现上各有什么优劣点呢?
// 闭包
function func1() {
// func1
}
function func2() {
// func2
}
function doSomething(func) {
return function() {
// do something...
return func
}
}
var func1 = doSomething(func1);
var func2 = doSomething(func2);
// 函数引用
function doSomething() {
// do something...
}
function func1() {
doSomething();
// func1
}
function func2() {
doSomething();
// func2
}
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
拿func1()来举例子
你两段代码的共同点是 执行func1()调用即执行了func1()的逻辑,又执行了doSomething的逻辑,
区别在于组织代码的时候在第二段代码里你将 doSomething()函数放在了 func1()里,而第一段
代码
func1相当与闭包,你可以在func1里面访问doSomething这个函数实现逻辑过程中的所有数据,但是在第二段
代码里显然没有这个功能
我说一个具体的闭包应用
假设
func1对两个数求和,func2对两个数求积,如下:现在我们需要为这两个函数分别添加一个日志打印的功能:
1、打印函数执行前的时间戳
2、执行函数
3、打印函数执行后的时间戳
4、返回结果
最直观的方法当然是,定义一个
log函数:然后将程序中所有调用
func1(a, b)和func2(a, b)的地方都分别替换为log(func1, a, b)和log(func2, a, b)可是问题来了,万一程序中调用了
func1和func2的地方很多,那不是得改到手软?你说可以用正则批量替换,但万一哪天想撤掉日志打印功能,岂不是又得换回来?
因此改函数名的方法行不通
这时,你又想出另一个方法,在
func1和func2函数体内注入打印时间戳的代码:可是问题又来了,万一有n个这样的函数,那岂不是要注入n次代码?
而且这样注入代码,可能还需要原函数的代码结构,容易出错
是时候祭出闭包大法一次性解决性解决这个问题了:
问题解决了,不需要改变调用
func1和func2的地方,也不需要往func1和func2里面注入代码,只需一次性定义
log,然后调用log(func1)就可以获得一个经过修饰的func1,假如日后想要把
log功能去掉,只需把var funcn = log(funcn)批量注释即可究其原因,是因为闭包在传递的时候,会携带自身的状态,
调用
log(func1)时,会返回一个函数,这个函数携带的状态就是(func <= func1)调用
log(func2)时,会返回一个函数,这个函数携带的状态就是(func <= func2)