• 柯里化原理
  • 如何实现柯里化
  • 柯里化的应用

一、柯里化原理

柯里化:在数学和计算机科学中,柯里化是一种使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。

前端使用柯里化的用途主要就应该是简化代码结构,提高系统的维护性,一个方法,只有一个参数,强制了功能的单一性,很自然就做到了功能内聚,降低耦合。

柯里化的优点:降低代码的重复,提高代码的适应性。

基于柯里化的基本原理,先将多个参数的函数执行拆分成两次传参执行:

 //有如下四个参数的函数
function add(a, b, c, d){
return a + b + c + d;
}
//实现一个两次传参的固定柯里化方法
function FixedParmasCurry(fu){
var _arg = Array.prototype.slice.call(arguments,1); //获取初始柯里化时传入的参数
return function(){
var newArg = _arg.concat(Array.prototype.call(arguments,0)); //拼接当前执行的参数
return fn.apply(this, newArg);
}
}
//测试一
var foo = FixedParmasCurry(add,1,2);
console.log(foo(3,4));//
//测试二
var fun = FixedParmasCurry(add,1);
console.log(fun(2,3,4));//

但是这并没有实现真正的柯里化,真正的柯里化应该是每次传任意参数,函数经过任意次执行,直到参数传入达到函数所需要的参数时返回函数的执行结果;也可以说是函数每次传入相应的参数,返回每个执行阶段的结果。为什么这么说呢?在柯里化应用中详细解析。

二、如何实现柯里化

 // 实现柯里化
function add(a, b, c, d){
return a + b + c + d;
}
// add函数柯里化的真正需求应该是下面这样:
var newAdd = Curry(add);
newAdd(1,2,3,4);
newAdd(1)(2)(3)(4);
newAdd(1,2)(3,4);
newAdd(1,2)(3)(4);
newAdd(1,2,3)(4);
newAdd(1)(2)(3,4);
newAdd(1)(2,3,4);
// 也就是说真正的Curry可以实现以上任意的执行组合 function Curry(fn,length){
var length = length || fn.length;
return function(){
if(arguments.length < length){
var combined = [fn].concat(Array.prototype.slice.call(arguments,0));
return Curry(FixedParmasCurry.apply(this,combined),length - arguments.length);
}else{
return fn.apply(this,arguments);
}
}
} function FixedParmasCurry(fn){
var _arg = Array.prototype.slice.call(arguments,1); //获取初始柯里化时传入的参数
return function(){
var newArg = _arg.concat(Array.prototype.slice.call(arguments,0)); //拼接当前执行的参数
return fn.apply(this, newArg);
}
}

实现分析:FixedParmasCurry(fn)本质上就是将已传入的参数作函数执行必要的参数直接执行,缺少对参数长度的判断。实现函数柯里化时初始化了必要参数的总长度length;然后每次计算还需要传入函数的长度,直到传入的参数arguments.length的长度大于或者等于需要的参数长度,就可以真正的执行函数了(23行)。

三、柯里化应用

例如下面这个模拟的ajax请求需求:

 function ajax(type,url,data){
var xhr = new XMLHTTPRequest();
xhr.open(type,url,true);
xhr.send(data);
}
//如果有需求是将同一个参数同时发送给三个连接,下面这种做法明显的出现了代码冗余
ajax('POST','www.test.com','name=keyin');
ajax('POST','www.test2.com','name=keyin');
ajax('POST','www.test3.com','name=keyin');
//Curry
var ajaxCurry = curry(ajax);
var post = ajaxCurry("POST");
post('www.test.com','name=keyin');
post('www.test.com2','name=keyin');
post('www.test.com3','name=keyin');

可能在示例中还不那么明显,至少可以想象一件事情,当多个业务功能有一部分基础实现是一致的,如果通过像示例这样的共用一个参数导入,除了减低代码的耦合度,还可以灵活的拆解合并功能需求。

JavaScript函数式编程——柯里化的更多相关文章

  1. 【译】理解JavaScript中的柯里化

    译文开始 函数式编程是一种编程风格,这种编程风格就是试图将传递函数作为参数(即将作为回调函数)和返回一个函数,但没有函数副作用(函数副作用即会改变程序的状态). 有很多语言采用这种编程风格,其中包括J ...

  2. javascript之反柯里化(uncurrying)

    在JavaScript中,当我们调用对象的某个方法时,其实不用去关心该对象原本是否被设计为拥有这个方法,这是动态类型语言的特点.可以通过反柯里化(uncurrying)函数实现,让一个对象去借用一个原 ...

  3. 简单粗暴详细讲解javascript实现函数柯里化与反柯里化

    函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...

  4. javascript中利用柯里化函数实现bind方法

    柯理化函数思想:一个js预先处理的思想:利用函数执行可以形成一个不销毁的作用域的原理,把需要预先处理的内容都储存在这个不销毁的作用域中,并且返回一个小函数,以后我们执行的都是小函数,在小函数中把之前预 ...

  5. 浅谈JavaScript中的柯里化函数

    首先,不可避免的要引经据典啦,什么是柯里化函数呢(from baidu): 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返 ...

  6. JavaScript函数的柯里化(currying)

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/currying.html 什么是js函数的currying /柯里化? 说到js的柯里化,相信很多朋友都会头大.或 ...

  7. JavaScript之函数柯里化

    什么是柯里化(currying)? 维基百科中的解释是:柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术.意思就是当函 ...

  8. 简单粗暴详细讲解javascript实现函数柯里化

    函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...

  9. JavaScript中的柯里化

    转载自:https://www.cnblogs.com/zztt/p/4142891.html 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Ha ...

随机推荐

  1. git 命令简洁手册

    1.从当前目录初始化 git init 2.对文件进行跟踪 或  将已跟踪的文件放到暂缓区 或 把有冲突的文件标记为已解决状态 git add <file> 3.从现有仓库克隆 git c ...

  2. leetcode39 组合总和

    这道题想到的就是dfs,在累加的和大于或等于target时到达递归树的终点. 代码如下: class Solution { public: vector<vector<int>> ...

  3. css3弹性盒子display:flex

    先看上面的代码,解释一下意思,看你能认识多少(后面有注释): .container { display: flex; //弹性布局 flex-direction: column; //容器内项目的排列 ...

  4. 2018.05.17 nace关于采购订单的配置笔记

    由于公司的打印都是使用nast作为记录表,在给日企中国客户做扩展时单独配置了一下nace的设置 ZM01作为采购订单批量打印的输出类型,ZM02作为采购订单创建变更时输出的pdf打印输出类型 1.TC ...

  5. Linux CentOS汉化系统

    u root切换为root用户 写入环境变量 echo "export LANG="zh_CN.UTF8"">>/etc/profile sourc ...

  6. spring配置注解context:annotation-config和context:component-scan区别

    Spring 中在使用注解(Annotation)会涉及到< context:annotation-config> 和 < context:component-scan>配置, ...

  7. lua学习笔记3--lua与c#交互

    LuaInterface是C#与Lua连接的桥梁 LuaInterface是一个开源项目工程,内部有两个核心DLL文件: LuaInterface.dll:在C#中操作Lua代码需要依赖该文件; lu ...

  8. mysql主主、mysql-proxy读写分离、keepalived高可用完美组合

    配置mysql主主复制 服务器A:172.16.100.9 服务器B:172.16.100.10 首先在服务器A和服务器B上各安装好单机版mysql5.7,安装好后,再继续下面的操作. 在服务器A和服 ...

  9. Design Hit Counter

    Design a hit counter which counts the number of hits received in the past 5 minutes. Each function a ...

  10. [转帖]postgresql 在等待服务器启动时超时

    postgresql 在等待服务器启动时超时 2018年12月24日 :: my_name_nb 阅读数 版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接 ...