深入理解javascript系列(十七):函数柯里化
之前的系列,我们介绍了什么是高阶函数。所有以函数作为参数的函数,都可以叫作高阶函数。并且我们常常利用高阶函数来封装一些公共逻辑。
本次,我们要继续学习,继续记录,柯里化。柯里化,其实就是高阶函数的一种特殊用法。
柯里化是指这样一个函数(假设叫做createCurry),它接收函数A作为参数,运行后能够返回一个新的函数,并且这个新的函数能够处理函数A的剩余参数。
文字总是不那么好去理解,下面我们就通过例子来理解吧。
假设有一个接收三个参数的函数A。
function A(a, b, c) {// to do something
}复制代码
又假设我们有一个已经封装好了的柯里化通用函数createCurry。他接收bar作为参数,能够将A转化为柯里化函数,返回结果就是这个被转化之后的函数。
var _A = createCurry(A);复制代码
那么_A作为createCurry运行的返回函数,能够处理A的剩余参数。因此下面的运行结果都是等价的。
_A(1, 2, 3);
_A(1,2)(3);
_A(1)(2,3);
_A(1)(2)(3);
A(1,2,3);复制代码
函数A被createCurry转化之后得到柯里化函数_A,_A能够处理A的所有剩余参数。因此柯里化也被称为部分求值。
在简单的场景下,我们可以不借助柯里化通用式来转化得到柯里化函数,仅凭借眼力自己封装。
例如,有一个简单的加法函数,它能够将自身的三个参数加起来并返回计算结果。
function add(a, b, c) {return a + b + c;
}复制代码
那么add函数的柯里化函数_add则可以写成:
function _add(a) {return function(b) {return function(c) {return a + b + c;}}
}复制代码
因此下面的运算方式是等价的。
add(1, 2, 3);
_add(1)(2)(3);复制代码
当然,柯里化通用式具备更加强大的能力,仅靠眼力劲可不行。因此我们更需要知道如何封装这样一个柯里化的通用式。
首先通过_add可以看出,柯里化函数的运行过程其实是一个参数收集过程,我们将每一次传入的参数收集起来,并在最里层进行处理。因此在实现createCurry时,可以借助这个思路来进行封装。
代码如下:
// arity 用来标记剩余参数的个数
// args 用来收集参数function createCurry(func, arity, args) {//第一次执行时,并不会传入arity,而是直接获取func参数的个数 func.lengthvar arity = arity || func.length;//第一次执行也不会传入args,而是默认为空数组var args = args || [];var wrapper = function() {//将wrapper中的参数收集到args中var _args = [].slice.call(arguments);[].push.apply(args, _args);//如果参数个数小于最初的func.length,则递归调用,继续收集参数if(_args.length < arity) {arity -= _args.length;return createCurry(func, arity, args);}//参数收集完毕,执行funcreturn func.apply(func, args);}return wrapper;
}复制代码
是不是有些不太容易理解,所以要多阅读几次。这个createCurry的封装其实是借助了闭包和递归,实现一个参数收集,并在收集完毕之后执行所有参数。
不知道您是否有发现,函数经过createCurry转化为一个柯里化函数后,最后执行的结果,不是正相当于执行函数自己吗?柯里化是不是把简单的问题复杂化了?
没错,柯里化确实是把简单的问题复杂化了,但在复杂化的同时,我们在使用函数时拥有了更多的自由度。对于函数参数的自由处理,正是柯里化的核心所在。
下面举一个常见的例子。
如果想要验证一串数字是否是正确的手机号,那么按照正常思路来做,可能就会写出代码如下唉:
fuction checkPhone(phoneNumber) {return /^1[34578]\d{9}$/.test(phoneNumber);
}复制代码
而如果想要验证是否是邮箱呢?你然后在写一个,可是我们还会遇到更多需要验证的消息,如“身份证、登录名、密码...”。为了偷懒,我们应该封装一个更为通用的函数,把待验证的正则表达式与将要被验证的字符串作为参数传入:
function check(reg, targetString) {return reg.test(targetSting);
}复制代码
但是这样封装之后,在使用时又会遇到问题,因为总是需要输入一串正则,一串字符,这样就导致使用时效率低下。
这个时候,我们就可以借助柯里化,在check的基础上再做一层封装,以简化使用。
var _check = createCurry(check);var checkPhone = _check(/xxxxxx/);
var checkEmail = _check(/xxxxxx/);复制代码
最后在使用时就会变得更加简洁与直观了。
checkPhone('13979227922');
checkEmail('xsxsx@163.com');复制代码
在这个过程中可以发现,柯里化能够应对更加复杂的逻辑封装。当情况变得多变时,柯里化依然能够应付自如。
虽然柯里化在一定程度上将问题复杂化,也让代码变得更加不容易理解,但是柯里化在面对复杂情况时的灵活性却让我们不得不爱。
深入理解javascript系列(十七):函数柯里化相关推荐
- JavaScript 专题之函数柯里化
JavaScript 专题系列第十三篇,讲解函数柯里化以及如何实现一个 curry 函数 定义 维基百科中对柯里化 (Currying) 的定义为: In mathematics and comput ...
- 深入详解python高级特性——函数柯里化(Currying)与反柯里化
前言:本章的内容本来很简单,但是涉及到的理论部分相对较多,想要彻底弄懂前因后果需要具备以下几个知识点, (1)python的高阶函数 (2)python的装饰器本质 (3)Python的functoo ...
- 打造属于自己的underscore系列(五)- 偏函数和函数柯里化
这一节的内容,主要针对javascript函数式编程的两个重要概念,偏函数(partial application) 和函数柯里化(curry)进行介绍.着重讲解underscore中对于偏函数应用的 ...
- 带你看懂javascript函数柯里化(currying)
1.什么是柯里化 这里参照百度百科: 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技 ...
- JavaScript 中函数 柯里化风格的运用
导语 当我第一次看见 柯里化 这个词语的时候,我也表现出一脸懵,在代码程序中,看见这种 "高大上"的一些词汇叫法的时候,下意识的会觉得这个概念很难很深奥,但是当冷静下来,去深究过后 ...
- JavaScript函数柯里化详解
目录 一.简单了解apply和call 二.什么是函数柯里化? 三.写一个公共的柯里化函数 四.创建一个灵活的柯里化函数 五.写一个可控制的执行时间的柯里化函数 一.简单了解apply和call ca ...
- 【JavaScript】函数柯里化
文章目录 1. 什么是函数柯里化 2. 柯里化常用场景 2.1 参数复用 2.2 提前返回 2.3 延迟执行 3. 经典例题 3.1 封装通用柯里化函数 3.2 创建一个灵活的多步执行的柯里化函数 3 ...
- JavaScript函数柯里化
一.简单了解apply和call call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向. call 和 appl ...
- 了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化
js基础知识中的作用域和闭包 一.作用域 1.作用域.自由变量简介 (1)作用域定义 (2)作用域实例演示 (3)自由变量定义 (4)自由变量实例演示 2.作用域链简介 (1)作用域链定义 (2)作用 ...
最新文章
- 笔记本独显无输出_高价位笔记本电脑推荐(一万一以上)
- SAP RETAIL 根据Allocation Rule去创建分配表
- 使用 plsql 时的配置信息(连远程数据库服务器 到 在本机安装 oracle )
- webpack+vue动态加载组件尝试
- python怎么理解函数的参数_Python中函数参数理解
- 485串口测试工具软件_【实例】如何用串口软件调试变频器?
- 图见-未来 | 创邻科技 Galaxybase免费版发布会回顾
- 风变编程,帮助你从零开始学习编程
- 【论文阅读】Tightly Coupled 3D Lidar Inertial Odometry and Mapping
- java 汽车类_汽车类 - java代码库 - 云代码
- 皇图中原青豫大战打到服务器维护,【九州皇图】青、豫国砸再现激情
- 20种简单美化照片PS技术
- 《A Traceable and Revocable Ciphertext-Policy Attribute-based Encryption Scheme Based》属性加密机制
- 高等数学:第一章 函数与极限(2)数列极限
- 2021十大手表品牌TOP排行榜
- 开源电子表格Luckysheet强势推出在线协作
- python基础:廖雪峰的官方网站Python(部分)笔记
- 魏副业而战:闲鱼无货源爆款热销产品推荐
- 2018ccpc吉林 C:JUSTICE 思维
- strace简单介绍
热门文章
- Ceph分布式存储学习指南1.10 iRODS
- GreenPlum的并行查询优化策略
- 用计算机自我介绍,计算机个人简历:计算机专业简历自我介绍【四篇】供参考使用(5页)-原创力文档...
- oracle隐藏游标,Oracle 存储过程隐藏游标
- android 串口调试adb,Android系统 debug 技巧(最全最强adb 串口调试命令)
- java heap space flex_Flash builder 4内存优化之java heap space解决办法
- Zookeeper基于Java访问-节点事件监听
- checkInterruptWhileWaiting
- 初探Spring MVC 请求处理流程
- ApplicationContext应用上下文获取方式