柯里化是什么?
- js柯里化指的是什么?
通俗点讲:比如一个函数接收两个参数,另一个函数只接收第一个参数,再返回一个函数接收第二个参数。
那么,这么做的好处是什么呢?请看下面示例:
//eg1:
function add(x, y) {
return x + y;
}
add(1,2) //3
function curryingAdd(x) {
return function(y){
return x + y
}
}
curryingAdd(1)(2)//3
柯里化应该怎么用?
2. 柯里化函数的特点:
2-1:参数复用(eg2):
解析:假如有很多地方需要验证字母的话,可以直接复用checoutLetter方法。省去了每次都要传正则的麻烦。
//eg2: 科里话函数与普通函数正则验证字符串的对比:
function check(reg, txt) {
return reg.test(txt)
}
check(/\d\g/, 'aaaa') //false
check(/[a-z]/g, 'aaaa')//true
function curringCheck(reg) {
return function(txt) {
console.log(reg.test(txt))
return reg.test(txt)
}
}
var checoutLetter = curringCheck(/[a-z]/g)
var checkoutNumber = curringCheck(/\d/g)
checoutLetter('aaa11') //true
checoutLetter(123) //false
checkoutNumber('aaa') //false
2-2: 提前确认(eg3):
解析:我们在做项目的过程中,封装一些dom操作可以说再常见不过,上面第一种写法也是比较常见,但是我们看看第二种写法。
它相对第一种写法就是自执行然后返回一个新的函数,这样其实就是提前确定了会走哪一个方法,避免每次都进行判断。
//eg3:
var on = function(element, event, handler) {
if (document.addEventListener) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
} else {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
}
}
var on = (function() {
if (document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
};
}
})();
//换一种写法可能比较好理解一点,上面就是把isSupport这个参数给先确定下来了
var on = function(isSupport, element, event, handler) {
isSupport = isSupport || document.addEventListener;
if (isSupport) {
return element.addEventListener(event, handler, false);
} else {
return element.attachEvent('on' + event, handler);
}
}
2-3: 延迟执行(eg4):
解析:延迟执行,没看太明白有什么应用场景和作用??:
补充:对象参数转换为数组 : Array.prototype.slice.call(arguments)
//eg4:
Function.prototype.bind = function (context) {
var _this = this
var args = Array.prototype.slice.call(arguments, 1)
return function() {
return _this.apply(context, args)
}
}
//解析:Array.prototype.slice.call(arguments)能够将arguments转成数组(IE除外)
//参考:https://www.cnblogs.com/littledu/archive/2012/05/19/2508672.html
//关于arguments类数组的介绍:https://www.cnblogs.com/minigrasshopper/p/8058679.html
var a={length:2,0:'first',1:'second'};
Array.prototype.slice.call(a) // ["first", "second"]
var b = Array.prototype.slice.call(a, 1);// ["second"]
// console.log(b.concat(Array.prototype.slice.call(a)))// ["second", "first", "second"]
练习: 以一道经典面试题作为收尾:
实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
答案:
function add() {
// console.log(arguments, '--arguments--')
var _args = Array.prototype.slice.call(arguments); //此处的arguments只接收一个参数,然后将其转化成类数组格式(返回其长度,和将每一项的值存到数组中)
var _adder = function() {
// console.log(...arguments, '--zhankai---') //此处的...arguments是将add(),也就是第一个括号以后的所有传参,进行了展开运算 (就是利用了柯里化的一个特性:参数复用)
_args.push(...arguments);
console.log(_adder, '--adder--')
return _adder;
};
_adder.toString = function () { //隐式转化:_adder()方法函数,去调用toString()方法,
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
console.log( add(1)(2)(3) )
console.log( add(1, 2, 3)(4))
console.log(add(1)(2)(3)(4)(5))
补充:
什么是隐式转化?以及它的使用场景?
1. js是弱类型语言,即在赋值的同时,也声明了它的使用类型。
2. 当给一个已经赋值的变量,再次赋值时,js会根据固定的规则来进行隐式转换。(这也是弱类型语言的一个特性)
详细介绍:www.jianshu.com/p/f6d3ef905…
举一个简单的例子帮助大家理解:
var num = 1;//Number
var num = '23';//String
console.log( num)//String 23
总结:
在整篇文章中,我们了解到了js柯里化的三个特性:参数复用,提前确认,延迟执行。大家平时在写代码的过程中,勤加思考,相信大家对柯里化的理解会更上一层楼。
如果觉得对你有帮助,请给作者一点小小的鼓励,
点个赞或者收藏吧。
有需要沟通的请联系我:微信( wx9456d ) 邮箱( allan_liu986@163.com )