简单粗暴详细讲解javascript实现函数柯里化
函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感;下面来一起看看究竟什么是函数柯里化:
维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第一个参数)的函数,并返回接受剩余的参数而且返回结果的新函数的技术。其由数学家Haskell Brooks Curry提出,并以curry命名。
概念往往都是干涩且难懂的,让我们用人话来解释就是:如果我们不确定这个函数有多少个参数,我们可以先给它传入一个参数,然后通过JS闭包(如若不懂JS闭包,请先学习闭包知识点再来学习本篇博文 https://www.cnblogs.com/dengyao-blogs/p/11475575.html )来进行返回一个函数,内部函数接收除开第一个参数外的其余参数进行操作并输出,这个就是函数的柯里化;
举个小例子:
场景(需求):
如果我们需要计算一个程序员每天的加班时间,那么我们的第一反应应该是这样;
; function time(x){ return overtime+=x; } time(); //1 time(); //3 time(); //6
上面的代码固然没有问题,可是需要每天调用都算加一下当天的时间,那么有没有可以偷懒的办法呢?有的!
function time(x){ return function(y){ return x+y; } } var times=time(0); times(3);
但是上面代码依然存在问题,在实际开发中很多时候我们的参数是不确定的,上面代码虽然简单的实现了柯里化的基本操作,但是对于参数不确定的情况是处理不了的;
我们再来把代码改建一下:
// 首先定义一个变量接收函数var overtime = (function() {//定义一个数组用来接收参数 var args = []; //这里运用闭包,调用外部函数返回一个内部函数 return function() { //arguments是浏览器内置对象,专门用来接收参数 //如果参数的长度为0即没有参数的时候 ) { //定义变量用来累加 ; //循环累加,用i和args的长度进行比较 , l = args.length; i < l; i++) { //进行累加操作 等价于time=time+args[i] time += args[i]; } // 返回累加的结果 return time; //如果arguments对象参数长度不为零,即有参数的时候 }else { //定义的空数组添加arguments参数作为数组项,第一个参数古args作为改变this指向,第二个参数arguments把剩余参数作为数组形式添加至空数组中 [].push.apply(args, arguments); } } })(); overtime(3.5); // 第一天 overtime(4.5); // 第二天 overtime(2.1); // 第三天 //... console.log( overtime() ); // 10.1
代码经过我们的改造已经实现了功能,但是这不是一个函数柯里化的完整实现,那么我们要怎么完整实现呢?
//定义方法currying,先传入一个参数var currying=function(fn){ //定义空数组装arguments对象的剩余参数 var args=[]; //利用闭包返回一个函数处理剩余参数 return function (){ //如果arguments的参数长度为0,即没有剩余参数 if(arguments.length===0){ //执行上面方法 return fn.apply(this,args) } console.log(arguments) //如果arguments的参数长度不为0,即还有剩余参数 //在数组的原型对象上添加数组,apply用来更改this的指向为args //将[].slice.call(arguments)的数组添加到原型数组上 Array.prototype.push.apply(args,[].slice.call(arguments)) //args.push([].slice.call(arguments)) console.log(args) //这里返回的arguments.callee是返回的闭包函数,callee是arguments对象里面的一个属性,用于返回正被执行的function对象 return arguments.callee } } //这里调用currying方法并传入add函数,结果会返回闭包内部函数 var s=currying(add); //调用闭包内部函数,当有参数的时候会将参数逐步添加到args数组中,待没有参数传入的时候直接调用 //调用的时候支持链式操作 s(1)(2)(3)();//也可以一次性传入多个参数
s(1,2,3);
console.log(s());
JS函数柯里化的优点:
1.可以延迟计算,即如果调用柯里化函数传入参数是不调用的,会将参数添加到数组中存储,等到没有参数传入的时候进行调用;
2.参数复用,当在多次调用同一个函数,并且传递的参数绝大多数是相同的,那么该函数可能是一个很好的柯里化候选。
简单粗暴详细讲解javascript实现函数柯里化的更多相关文章
- 简单粗暴详细讲解javascript实现函数柯里化与反柯里化
函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...
- JavaScript之函数柯里化
什么是柯里化(currying)? 维基百科中的解释是:柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术.意思就是当函 ...
- Swift函数柯里化(Currying)简谈
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面简单说说Swift语言中的函数柯里化.简单的说就是把接收多 ...
- JavaScript中的事件循环机制跟函数柯里化
一.事件循环机制的理解 test();//按秒输出5个5 function test() { for (var i = 0; i < 5; i++) { setTimeout(() => ...
- Javascript函数柯里化(curry)
函数柯里化currying,是函数式编程非常重要的一个标志.它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去.我们依靠这个特性编写很多优雅酷炫的代 ...
- 深入理解javascript函数进阶系列第二篇——函数柯里化
前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...
- JavaScript函数柯里化的一些思考
1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函 ...
- 精读JavaScript模式(六),Memoization模式与函数柯里化的应用
假期就这么结束了!十天假就有三天在路上,真的难受!想想假期除了看了两场电影貌似也没做什么深刻印象的事情.流浪地球,特效还是很赞,不过对于感情的描写还是逃不掉拖沓和尴尬的通病,对于国产科幻还是抱有支持的 ...
- 一道javascript面试题(闭包与函数柯里化)
要求写一个函数add(),分别实现能如下效果: (1)console.log(add(1)(2)(3)(4)()); (2)console.log(add(1,2)(3,4)()); (3)conso ...
随机推荐
- Docker 架构原理及简单使用
提示:文中有些内容为大神的博客内容,就不统一标注那里引用,只是再最下面标注参考连接谢谢 一.简介 1.了解docker的前生LXC LXC为Linux Container的简写.可以提供轻量级的虚拟化 ...
- IBM实习工作(一)
2019.1.21 今天的任务是完成会计是否在岗配置表格增加操作记录,任务描述:1. [会计是否在岗配置] 查询结果界面: 修改人编码/修改人/修改时间 字段:2. 字段取值为[会计是否在 ...
- vue-cli中的跨域之proxytable
为什么会有跨域? 浏览器有一个叫做同源策略的东西.同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互.这是一个用于隔离潜在恶意文件的重要安全机制. 同源策略规定了如果两个页面的协 ...
- python对常见数据类型的遍历
本文将通过for ... in ...的语法结构,遍历字符串.列表.元组.字典等数据结构. 字符串遍历 >>> a_str = "hello itcast" &g ...
- intellij idea与github整合管理代码
各位看官大家好,博主每每在公司学习新知识写代码时都需要通过U盘带回家来继续每天的学习,觉得这样实在麻烦,于是今天就整合了一下github来完成代码的管理. 开始之前我们需要准备三样东西:1.intel ...
- Mock Server的搭建
一.概述 我们系统与第三方开票系统有交互,场景是我们系统请求第三方开票系统,第三方开票系统根据我们的请求数据,生成开票信息然后返回发票号或异常信息,我们根据返回的信息做对应的处理.因为配合上存在一些障 ...
- 拼写单词[哈希表]----leetcode周赛150_1001
题目描述: 给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我 ...
- 记录 Java 的 BlockingQueue 中的一些坑
最近学习了 BlockingQueue,发现 java 的 BlockingQueue 并不是每一个实现都按照 BlockingQueue 的语意来的,其中有不少坑. 直接上代码吧: 1.关于Prio ...
- 解决Selenium弹出新页面无法定位元素问题(Unable to locate element)
Python 2.7 IDE Pycharm 5.0.3 环境细节详见Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登录 对于同一页面无法定位元素问题请见姊妹篇解 ...
- Python 标识符说明
在Python中,标识符有字母.数字.下划线组成 所有标识符都可以包括英文.数字.下划线,但不能以数字开头 Python标识符区分大小写 ※以下划线开头的标识符有特殊含义. 例如:以单下划线开头(_t ...