在解释什么是柯里化函数之前呢,先搞明白另一个概念——高阶函数。
高阶函数,就是一个函数可以接收另一个函数作为参数,看一个例子:
function higerFunc(fn){
return fn()
}
higerFunc(function(){
console.log('hello')
})
柯里化函数其实就是高阶函数,它可以将函数拆成两步来执行(延期执行),怎么理解呢?
我们还是看一个例子:
//普通函数
function check(reg, txt) {
return reg.test(txt)
}
check(/\d+/g, 'test')
check(/\d+/g, 'abc123')
check(/\d+/g, '789')
// Curry化函数,将第一个参数拆分出来复用,第二个参数作为变量。
function curryingCheck(reg) {
return function(txt) {
return reg.test(txt)
}
}
var hasNumber = curryingCheck(/\d+/g)
hasNumber('test')
hasNumber('abc123')
hasNumber('789')
大家能看出区别吗?
柯里化之前的函数,虽然可以一步到位,但正则得写多遍吧,多麻烦啊!而使用了柯里化,虽然拆成两步执行,但可以复用正则表达式,省事不少呢~~
好,下面看一个柯里化的实际使用场景,大家就能深刻理解柯里化的好处了。
大家看这样一个需求:
当点击一个按钮时,如何将额外的数据,传入到这个事件的回调函数中?
我们试着写一下:
var dom = document.getElementById('btn')
function fn(obj){
console.log(obj)
}
var data = {id:1,title:'this is a test'}//这个data如何传入fn?
dom.addEventListener('click',fn,false)//无法传入fn(data)
可以这么改造一下即可:
dom.addEventListener('click',function(e){
fn.call(dom,data)
},false)
这不就行了?且慢!
如果dom上的click事件挂载了多个,我只想移除特定的某一个,怎么办?
var dom = document.getElementById('btn')
function fn(obj){
console.log(obj)
}
var data = {id:1,title:'this is a test'}//这个data,如何传入fn?
dom.addEventListener('click',function(e){
console.log('第1个click事件') //我只想移除这个click
fn.call(dom,data)
},false)
dom.addEventListener('click',function(e){
console.log('第2个click事件')//我要保存这个click
fn.call(dom,e)
},false)
如果用了匿名函数,我们只能将全部click事件移除:
dom.removeEventListener('click')//dom上挂载的click事件全部被移除了
怎么办呢?
这就慢慢绕到柯里化上来了,我们可以将fn柯里化一下:
var dom = document.getElementById('btn')
function curryFn(obj){
return function(){
console.log('data:',obj)//内存持有上下文
console.log('event:',arguments)//内函数的参数
}
}
var data = {id:1,title:'this is a test'}//这个data,如何传入fn?
var clickAction = curryFn(data)
dom.addEventListener('click',clickAction,false)
//2s后移除事件
setTimeout(function(){
dom.removeEventListener('click',clickAction)
},2000)
我们再将curryFn稍加改造,提升一点逼格:
function curryFn(){
var outParams = [].slice.call(arguments) //外层函数的参数,也就是data
return function(){
console.log('data:',outParams)
console.log('event:',arguments)//内层函数的参数,也就是event
}
}
网友评论