JavaScript函数式编程——柯里化
- 柯里化原理
- 如何实现柯里化
- 柯里化的应用
一、柯里化原理
柯里化:在数学和计算机科学中,柯里化是一种使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。
前端使用柯里化的用途主要就应该是简化代码结构,提高系统的维护性,一个方法,只有一个参数,强制了功能的单一性,很自然就做到了功能内聚,降低耦合。
柯里化的优点:降低代码的重复,提高代码的适应性。
基于柯里化的基本原理,先将多个参数的函数执行拆分成两次传参执行:
//有如下四个参数的函数
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函数式编程——柯里化的更多相关文章
- 【译】理解JavaScript中的柯里化
译文开始 函数式编程是一种编程风格,这种编程风格就是试图将传递函数作为参数(即将作为回调函数)和返回一个函数,但没有函数副作用(函数副作用即会改变程序的状态). 有很多语言采用这种编程风格,其中包括J ...
- javascript之反柯里化(uncurrying)
在JavaScript中,当我们调用对象的某个方法时,其实不用去关心该对象原本是否被设计为拥有这个方法,这是动态类型语言的特点.可以通过反柯里化(uncurrying)函数实现,让一个对象去借用一个原 ...
- 简单粗暴详细讲解javascript实现函数柯里化与反柯里化
函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...
- javascript中利用柯里化函数实现bind方法
柯理化函数思想:一个js预先处理的思想:利用函数执行可以形成一个不销毁的作用域的原理,把需要预先处理的内容都储存在这个不销毁的作用域中,并且返回一个小函数,以后我们执行的都是小函数,在小函数中把之前预 ...
- 浅谈JavaScript中的柯里化函数
首先,不可避免的要引经据典啦,什么是柯里化函数呢(from baidu): 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返 ...
- JavaScript函数的柯里化(currying)
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/currying.html 什么是js函数的currying /柯里化? 说到js的柯里化,相信很多朋友都会头大.或 ...
- JavaScript之函数柯里化
什么是柯里化(currying)? 维基百科中的解释是:柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术.意思就是当函 ...
- 简单粗暴详细讲解javascript实现函数柯里化
函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...
- JavaScript中的柯里化
转载自:https://www.cnblogs.com/zztt/p/4142891.html 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Ha ...
随机推荐
- SRCNN代码分析
代码是作者页面上下载的matlab版.香港中文大学汤晓鸥教授.Learning a Deep Convolutional Network for Image Super-Resolution. htt ...
- css滚动条美化
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 5px; height: 5px; background-color: #F5F5 ...
- 007-Linux 查看端口
1.使用ss 查看 ss 一般用于转储套接字统计信息.它还可以显示所有类型的套接字统计信息,包括 PACKET.TCP.UDP.DCCP.RAW.Unix 域等. ss -lntpd | grep : ...
- Windows添加启动项的两种方法
方案1直接将脚本放到启动文件夹里面 C:\Users\XXX\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 方案2 Win ...
- Scala面向对象03
- openstack核心组件--glance镜像(2)
一.glance介绍: Glance是Openstack项目中负责镜像管理的模块,其功能包括虚拟机镜像的查找.注册和检索等. Glance提供Restful API可以查询虚 ...
- AcitveReocrd事件和关联操作
ActiveRecord预定义的事件,都在 yiidbBaseActiveRecord 中进行了明确: abstract class BaseActiveRecord extends Model ...
- 3年磨一剑,我的前端数据 mock 库 http-mock-middleware
不好意思,离开博客园4年多了,一回来就是为自己打广告,真是害羞啊... http-mock-middleware 是我最近完成的一个前端数据 mock 库.它是我汇总近3年工作经验而诞生的一个工具,使 ...
- LeetCode.1200-最小绝对值差(Minimum Absolute Difference)
这是小川的第次更新,第篇原创 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第268题(顺位题号是1200).给定一个由不同的整数组成的数组arr,找到所有对元素,其中任意两个元素的绝 ...
- 前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输
HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...