把接收多个参数的函数转换成只接收一个参数的函数,并返回一个的函数,这个过程叫柯里化 (做到最大程度上的复用)
- 参数复用
- 延迟计算
- 动态创建
例一:获取URL
// 普通函数
function getUrl(protocol, host, path) {
return `${protocol}://${host}/${path}`
}
const baiduIndex = getUrl('https','www.baidu.com','index') // https://www.baidu.com/index
const taobaoIndex = getUrl('https','www.taobao.com','index') // https://www.taobao.com/index
const baiduUser = getUrl('https','www.baidu.com','user') // https://www.baidu.com/user
const taobaoUser = getUrl('https','www.taobao.com','user') // https://www.taobao.com/user
// 柯里化
function getUrl(protocol) {
return (host) {
return (path) {
return `${protocol}://${host}/${path}`
}
}
}
const domain = getUrl('https')
const baidu = domain('www.baidu.com')
baidu('index') // https://www.baidu.com/index
baidu('user') // https://www.baidu.com/user
const taobao = domain('www.taobao.com')
taobao('index') // https://www.taobao.com/index
taobao('user') // https://www.taobao.com/user
例二:正则校验
// 普通函数
function check(regexp, str) {
return regexp.text(str)
}
check(/^1[3456789]\d{9}$/, '18888482270') // true
check(/^1[3456789]\d{9}$/, '12345678900') // false
check(/^[+]{0,1}(\d+)$/, 100) // true
check(/^[+]{0,1}(\d+)$/, 'abc') // false
// 柯里化
function check(regexp) {
return (str) {
return regexp.text(str)
}
}
const isPhone = check(/^1[3456789]\d{9}$/)
isPhone('18888482270') // true
isPhone('12345678900') // false
const isInteger = check(/^[+]{0,1}(\d+)$/)
isInteger(100) // true
isInteger('abc') // false
例三:动态添加事件函数
如果要兼容现代浏览器和IE浏览器的添加事件方法
// 通常会这么写(每次添加的时候都得判断一次)
const addEvent = function (elem, type, fn, cature) {
if (window.addEventListener) {
elem.addEventListener(type, (e) => fn.call(elem, e), capture)
} else if (window.attachEvent) {
elem.attachEvent('on' + type, (e) => fn.call(elem, e)
}
}
// 柯里化
const addEvent = (function () {
if (window.addEventListener) {
return (elem, type, fn, capture) => {
elem.addEventListener(type, (e) => fn.call(elem, e), capture)
}
} else {
return (elem, type, fn, capture) => {
elem.attachEvent('on' + type, (e) => fn.call(elem, e)
}
}
})()