数中使用处理后的结果
function sum(x){
x = x + 1
return function (y){
y = y * 2
return x + y
}
}
console.log(sum(1)(2))
当某一层的函数输出结果出现问题的时候就可以到对应的地方去修改就可以了
好处二:逻辑的复用
定制函数,将重复使用的参数定制成一个函数使用,减少代码量和工作量
// 场景:我们经常需要将5与其他数字相加
// 未复用前
function sum(m,n){
m = m * m
return m + n
}
console.log(sum(5,10))
console.log(sum(5,100))
console.log(sum(5,1000))
console.log(sum(5,10000))
// 柯里化后
function sum(m){
m = m * m
return function(n){
return m + n
}
}
var add5 = sum(5)
add5(10)
add5(100)
add5(1000)
add5(10000)
自动柯里化函数的实现
目的:通过封装柯里化函数来实现传入一个普通函数自动柯里化的功能
柯里化函数的实现
function myCurrying(fn) {
// 不确定接收几个参数就用...args来接收
function curried(...args){
// 判断当前已经接受的参数的个数,和参数本身需要接受的参数是否已经一致了
// 一旦接收完后就不再接收了
if(args.length >= fn.length){
// 如果调用的时候有绑定this,就直接绑定到fn上
return fn.apply(this,args)
// return fn.call(this,args) 也可以
}else{
// 新函数接收后面的参数
function curried2(...args2) {
// 后来的参数要与之前的函数进行拼接,然后再递归调用
return curried.apply(this,args.concat(args2))
}
return curried2
}
}
return curried
}
自动柯里化函数的使用
// 要进行柯里化的普通函数
function sum(m,n){
m = m * m
return m + n
}
// 自动柯里化函数的封装
function myCurrying(fn) {
...
}
var currySum = myCurrying(sum)
console.log(currySum(10)(10)) //110
console.log(currySum(10,10)) //110
普通函数使用柯里化的注意事项
如果是一个一个参数传的话就不能传入多于原本普通函数所需的参数,否则会将前面的看做是一个函数从而报错
// 要进行柯里化的普通函数
function sum(m,n){
m = m * m
return m + n
}
// 自动柯里化函数的封装
function myCurrying(fn) {
...
}
var currySum = myCurrying(sum)
console.log(currySum(10)(10)(1))
而如果输入的参数少于原本普通函数所需的参数,则会返回一个接受剩余参数的函数
var currySum = myCurrying(sum)
console.log(currySum(10))
// [Function: curried2]
利用这一特点补充一下柯里化的第三个好处
好处三:延迟运行/计算
要求:柯里化了后的函数,它返回一个新的函数,新的函数接收可分批次接受新的参数,延迟到最后一次计算,我们可以任意传入参数,当不传参数的时候,输出计算结果
function currying(fn) {
var allArgs = []; // 用来接收参数
return function next(...args) {
var args1 = [].slice.call(args);
// 判断是否执行计算
if (args1.length > 0) {
allArgs = allArgs.concat(args1); // 收集传入的参数,进行缓存
return next;
} else {
return fn.apply(null, allArgs); // 符合执行条件,执行计算
}
}
}
补充slice( )
的说明 : slice() 方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。
使用1:
function sum(m, n) {
m = m * m
return m + n
}
function currying(fn) {
...
}
var currySum = currying(sum)
console.log(currySum(10)(10)(1)(10)()) // 输出结果:110
// 传入多少个都无所谓,到时候只要需要的参数就行,也不会报错
// 后面一定要加上括号,因为传入空参数是执行的条件,不加则会返回一个接受剩余参数的函数
使用2:
function sum(...args) {
var m = 0
for (var i = 0; i < args.length; i++) {
m += args[i];
}
return m;
};
function currying(fn) {
...
}
var currySum = currying(sum)
console.log(currySum(10)(10)(1)(10)()) // 输出结果:31