函数柯里化
概念
- 向一个函数里面传入若干参数,然后返回一个没有副作用的纯函数,从而达到参数复用的效果
使用场景
参数复用
- 当在多次调用同一个函数,并且传递的参数绝大多数是相同的,那么就可以用柯里化进行函数的复用
function getHtml(http) {
return function (hostname, pathname) {
return `${http}${hostname}${pathname}`
}
}
const htp = getHtml('https://');
console.log(htp('baidu', '.com'));
延时执行
const addEvent = (function () {
if (window.addEventListener) {
return function (element, type, listener, useCapture) {
element.addEventListener(type, function (e) {
listener.call(element, e)
}, useCapture)
}
} else if (window.attachEvent) {
return function (element, type, listener) {
element.attachEvent('on' + type, function (e) {
listener.call(element, e)
})
}
}
})()
let button = document.querySelector('button');
addEvent(button, 'click', (e) => { console.log('点击了按钮') }, true)
提前确认
- 当多次调用内部判断,可以提前返回第一次判断结果给外部接受
示例
const add = function () {
let args = Array.prototype.slice.call(arguments);
let next = function () {
args.push(...arguments);
return next;
}
next.toString = function () {
return args.reduce(function (a, b) {
return a + b
})
}
return next;
}
console.log( add(1)(2, 5)(3)(4) )
console.log( typeof add(1)(2, 5)(3)(4) )
console.log( +add(1)(2, 5)(3)(4) )
add(1)
add(1)(2)
add(1)(2)(3)
add(1)(2)(3)(4)
add(1)(2,3)
add(1,2)(3)
add(1,2,3)
currying实现
function currying(fn) {
return function next() {
let args = Array.prototype.slice.call(arguments);
if (args.length >= fn.length) {
return fn.call(this, args);
}
return function (...arg) {
return next(...args, ...arg);
}
}
}
function addNum(a, b, c) {
return a + b + c;
}
const addCurry = currying(addNum);
console.log(addCurry(1)(2)(3));
console.log(addCurry(1));
console.log(addCurry(1)(2));
console.log(addCurry(1)(2, 3));
console.log(addCurry(1, 2)(3));
console.log(addCurry(1, 2, 3));
参考文献
函数柯里化 - 清水渡白吟堤你如风 - 博客园 (cnblogs.com)