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 ...
随机推荐
- Android判断view在屏幕可见
/** * 判断当前view是否在屏幕可见 */public static boolean getLocalVisibleRect(Context context, View view, int of ...
- Kettle 排序记录的使用(Sort rows)
排序行的步骤根据您指定的字段和它们是否应该按升序或降序排序当行数超过指定的排序大小(默认为100万行)时候,kettle必须使用临时文件排序行.步骤名称:名称在整个转换中应该是唯一的排序目录:默认当前 ...
- React Native常用的第三方开源库
记录一下自己暂目前了解和使用的一些开源库和官方文档和优秀博客介绍,希望对你有帮助☺️: 1.Toast: https://github.com/magicismight/react-native-ro ...
- 删除指定路径下固定格式,以.log结尾、三天前的文件,或删除空的日志文件
师出‘百测’besttest 删除指定路径下固定格式,以.log结尾.三天前的文件,或删除空的日志文件. 日志文件格式:XXXX_2019-01-01.log. import os,datetime ...
- 【POJ - 1970】The Game(dfs)
-->The Game 直接中文 Descriptions: 判断五子棋棋局是否有胜者,有的话输出胜者的棋子类型,并且输出五个棋子中最左上的棋子坐标:没有胜者输出0.棋盘是这样的,如图 Samp ...
- PHP SQL注入
开发者容易遗漏的输入点: HTTP头 X-Forwarded-For 获取用户ip User-Agent 获取浏览器 Referer 获取之 ...
- SpringBoot消息队列之-rabbitMQ
一.概述 1.在大多应用中,我们系统之间需要进行异步通信,即异步消息. 2.异步消息中两个重要概念:消息代理(message broker)和目的地(destination) 当消息发送者发送消息以后 ...
- iterm 2快捷键
快捷键 作用说明 command + f 搜索&查找,如果输入搜索内容后,按下 tab 键,就会 iTerm 自动帮选中搜索关键词,并且自动的帮我们复制到了剪贴板中.如果输入的是 shift+ ...
- C# MVC MVP
https://www.codeproject.com/Articles/613682/Your-first-program-using-MVC-pattern-with-Csharp-W https ...
- python多进程单线程+协程实现高并发
并发:看起来像同时运行就是并发 并行:同一时间同时被执行叫做并行,最大并行数就是CPU核数 协程不是实实在在存在的物理基础和操作系统运行逻辑,只是程序员从代码层面避开了系统对遇到IO的程序会切走CPU ...