美文网首页
一起学习柯里化

一起学习柯里化

作者: isSunny | 来源:发表于2019-07-26 17:37 被阅读0次

柯里化,第一次听这个词的时候一脸懵逼,百度上看了一些大佬的文章,在这里和大家一起学习一下什么是柯里化。

官方解释:柯里化,英文currying,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

说的还是很难懂啊,直接上个简单🌰吧,就能明白了,拿我们最常见的add函数

//正常add(x,y)函数
function add(x,y){
    return x+y;
}
//柯里化后的函数
function curryAdd(x){
    return function(y){
        return x+y;
    }
}
console.log(add(1,2));//3
console.log(curryAdd(1)(2));//3

从上面例题我们可以看出来,就是函数把参数变成了先用一个函数接收部分参数,然后返回一个函数去处理剩余的参数。

直接敲代码吧,奉上封装好的通用方法

1.简单版
function curry(fn){
    var args =Array.prototype.slice.call(arguments,1);
    return function(){
        var _args = Array.prototype.slice.call(arguments);//新的参数
        var newArgs = args.concat(_args);
        return fn.apply(this,newArgs);//apply不要忘记哦~~
    }
}
function add(a, b) {
    return a + b;
}

var f1 = curry(add,1,2);
console.log(f1()); //3
var f2 = curry(add,1);
console.log(f2(2)); //3
var f3 = curry(add);
console.log(f3(1, 2)) // 3

emm,这一般是简单版,不能链式调用,也就是如f3(1)(2);
废话不多说,直接上加强版

2.加强版
function curry(fn){
    var args = Array.prototype.slice.call(arguments,1);
    var len = fn.length;//参数长度
    return function(){
        var _args = Array.prototype.slice.call(arguments);//新的参数
        var newArgs = args.concat(_args);//将所有参数集合在一起
        if(newArgs.length<len){
            //判断当前函数的参数和期望函数参数
            return curry.call(this,fn,...newArgs);//如果不够,递归调用
        }else{
            return fn.apply(this,newArgs);;//如果够,执行函数
        }
    }
}
function add(x,y){
    return x+y;
}
var f1 = curry(add)
console.log(f1(2)(1));//3
var f2 = curry(add,1);
console.log(f2(2));//3
var f3 = curry(add,1,2);
console.log(f3());//3
柯里化有什么好处呢?

柯里化有三个常见的作用:
详细可以参考这一篇文章JS中的柯里化(currying

  1. 参数复用;
  2. 提前返回;
  3. 延迟计算/运行。
bind实现柯里化:

具体可以看我写过的这篇文章bind的运用和bind的实现

最后跟我一起看一道经典的curry面试题

实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;

上面写的通用版,只针对有特定参数个数的函数适用,所以这道题还要重新思考一下。
由于这道题传入的参数个数不固定,这里就需要使用函数的toString来完成。

  • 法一:
function add(){
    var args = Array.prototype.slice.call(arguments);
    var fn = function(){
        //直接利用闭包的特性保存args并收集所有的参数值
         args.push(...arguments);//es6写法,
         return  add(...args);//es6写法
        // es5写法 add.apply(null,args);
        //也可以直接返回fn
        //return fn;        
    }
 // 利用隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    fn.toString = function(){
        return args.reduce(function(a,b){
            return a+b;
        })
    }
    return fn;
}
console.log(add(1)(2)(3) );//6
console.log(add(1, 2, 3)(4)); //10
console.log(add(1)(2)(3)(4)(5));//15
  • 法二:
function add(){
    var args = Array.prototype.slice.call(arguments);
    var fn = function(){
        var _args = Array.prototype.slice.call(arguments);
        var newArgs = args.concat(_args);//参数拼接
        return  add.apply(null,newArgs);//es5写法
        // es6写法 add(...newArgs);
    }
    fn.toString = function(){
        return args.reduce(function(a,b){
            return a+b;
        })
    }
    return fn;

}

console.log(add(1)(2)(3) );//6
console.log(add(1, 2, 3)(4)); //10
console.log(add(1)(2)(3)(4)(5));//15

其实方法一和方法二都是一样的,只不过是有一些es5和es6上写法差别,就分开写了。

这里说一下为啥需要使用函数的toString
当我们执行函数,直接参与计算的时候,会隐式调用toString,直接将函数体转换为字符串参与计算。

function a(){return 10};
console.log(a+20);//function a(){return 10}20

但是如果我们重写toString方法,函数参与计算时候,就可以输出我们想要的结果了。

function a(){return 10};
a.toString = function(){
    return 20;
}
console.log(a+20);//40

现在应该是可以理解了吧~~~就不多说了。

相关文章

  • 一起学习柯里化

    柯里化,第一次听这个词的时候一脸懵逼,百度上看了一些大佬的文章,在这里和大家一起学习一下什么是柯里化。 官方解释:...

  • 手写简单.bind()实现

    手写一个实现柯里化的.bind() 柯里化:《函数柯里化小结》柯里化:前端开发者进阶之函数柯里化Currying ...

  • 函数式编程(三)—— 柯里化

    柯里化Lodash中的柯里化 —— curry()案例柯里化原理模拟柯里化总结 【函数式编程总体设计】 之前讲了函...

  • [译]JavaScript中的函数柯里化

    原文 Currying in JS 函数柯里化 函数柯里化以Haskell Brooks Curry命名,柯里化是...

  • 简单理解JavaScript中的柯里化和反柯里化

    简单理解JavaScript中的柯里化和反柯里化 前言 本文旨在让大家简单理解柯里化和反柯里化,这里不做深入探究,...

  • 简单理解JavaScript中的柯里化和反柯里化

    简单理解JavaScript中的柯里化和反柯里化 前言 本文旨在让大家简单理解柯里化和反柯里化,这里不做深入探究,...

  • js柯里化

    标签: js柯里化 js柯里化 柯里化是什么在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成...

  • 柯里化和反柯里化

    一、柯里化 定义函数柯里化就是把一个函数中的一些可以固定的参数固定后生成新的函数比如一个函数: 现在有一个需求:就...

  • swift 柯里化

    swift 柯里化 柯里化 1、什么是柯里化? 柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一...

  • JS函数式编程之柯里化

    JS函数式编程之柯里化 为什么要了解柯里化 柯里化是函数式编程必须要使用的. 这里我们就先介绍下什么是柯里化, 然...

网友评论

      本文标题:一起学习柯里化

      本文链接:https://www.haomeiwen.com/subject/fuekrctx.html