函数柯里化
通用实现
function curry(fn, ...args) {
if (args.length >= fn.length) return fn(...args);
return function (...args2) {
return curry(fn, ...args, ...args2);
}
}
对于如何理解curring的实现 暂时参照JS中的柯里化 及 精巧的自动柯里化实现
有空会更深入的理解一下
概念(wiki): curring 是把接受多个参数的函数变成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
示例
function add(x,y) {
return x + y
}
//curring 处理
function curringAdd (x) {
return function (y) {
return x + y
}
}
add(1, 2) // 3
curringAdd(1)
curringAdd(1)(2)
就是处理一部分参数 返回一个函数 用于处理剩下的参数
为什么要用curring呢?
- 参数复用
- 提前确认
- 延迟运行
参数复用
function check(reg, txt){
return reg.test(txt)
}
check(/\d+/g, 122)
check(/[a-z]+/g, 'aaa')
check(/\d+/g, 'text')
// 如果我们要不同的地方都要验证同一个正则规则,那么第一参数就可以进行复用了
function curringCheck (reg) {
return function(text) {
return reg.test(text)
}
}
let isNum = curringCheck(/\d+/g)
let isString = curringCheck(/[a-z]+/g)
isNum(123)
isNum(text)
isString('ret')
这样就实现了参数复用(我们经常用到哪些 参数复用 的情况 什么情况下考虑使用curring 达到参数复用呢?)
提前确认
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);
};
}
})();
上面代码和下面的柯里化以后的区别是 我们在使用addEvent函数的时候第二种写法 已经知道我们要用的是 addEventListener还是attachEvent,而第一种写法要判断用哪个,所以柯里化就提前确认了
延迟运行
Function.prototype.bind = function (context) {
var _this = this
var args = Array.prototype.slice.call(arguments, 1)
return function() {
return _this.apply(context, args)
}
}