1、什么是柯里化

这里参照百度百科:

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

一句话概述:

柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术

函数柯里化有什么用:
我这里放几张知乎大佬的回答:




是不是还是搞不懂它是什么意思,没关系我也不懂,我们接着往下看,

2、一个简单的柯里化函数

function sum (a, b, c) {console.log(a + b + c);
}
sum(1, 2, 3); // 6

毫无疑问,sum 是个简单的累加函数,接受3个参数,输出累加的结果。

假设有这样的需求,sum的前2个参数保持不变,最后一个参数可以随意。那么就会想到,在函数内,是否可以把前2个参数的相加过程,给抽离出来,因为参数都是相同的,没必要每次都做运算。

如果先不管函数内的具体实现,调用的写法可以是这样: sum(1, 2)(3); 或这样 sum(1, 2)(10); 。就是,先把前2个参数的运算结果拿到后,再与第3个参数相加。

这其实就是函数柯里化的简单应用。

总结来说:柯里化的目的是,减少代码冗余,以及增加代码的可读性

3、柯里化的好处

1、参数复用
2、提前确认
3、延迟运行

1.参数复用

//上面的示例是一个正则的校验,正常来说直接调用check函数就可以了,
//但是如果我有很多地方都要校验是否有数字,
//其实就是需要将第一个参数reg进行复用,
//这样别的地方就能够直接调用hasNumber,hasLetter等函数,
//让参数能够复用,调用起来也更方便。// 正常正则验证字符串 reg.test(txt)// 函数封装后
function check(reg, txt) {return reg.test(txt)
}check(/\d+/g, 'test')       //false
check(/[a-z]+/g, 'test')    //true// Currying后
function curryingCheck(reg) {return function(txt) {return reg.test(txt)}
}var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)hasNumber('test1')      // true
hasNumber('testtest')   // false
hasLetter('21212')      // false

2、提前确认

我们在做项目的过程中,封装一些dom操作可以说再常见不过,
上面第一种写法也是比较常见,但是我们看看第二种写法,
它相对一第一种写法就是自执行然后返回一个新的函数,
这样其实就是提前确定了会走哪一个方法,避免每次都进行判断。
var on = function(element, event, handler) {if (document.addEventListener) {if (element && event && handler) {element.addEventListener(event, handler, false);}} else {if (element && event && handler) {element.attachEvent('on' + event, handler);}}
}var on = (function() {if (document.addEventListener) {return function(element, event, handler) {if (element && event && handler) {element.addEventListener(event, handler, false);}};} else {return function(element, event, handler) {if (element && event && handler) {element.attachEvent('on' + event, handler);}};}
})();//换一种写法可能比较好理解一点,上面就是把isSupport这个参数给先确定下来了
var on = function(isSupport, element, event, handler) {isSupport = isSupport || document.addEventListener;if (isSupport) {return element.addEventListener(event, handler, false);} else {return element.attachEvent('on' + event, handler);}
}

3、延迟运行

//像我们js中经常使用的bind,实现的机制就是Currying.
Function.prototype.bind = function (context) {var _this = thisvar args = Array.prototype.slice.call(arguments, 1)return function() {return _this.apply(context, args)}
}

4、封装柯里化(重点)

function curry (fn, currArgs) {return function() {let args = [].slice.call(arguments);// 首次调用时,若未提供最后一个参数currArgs,则不用进行args的拼接if (currArgs !== undefined) {args = args.concat(currArgs);}// 递归调用if (args.length < fn.length) {return curry(fn, args);}// 递归出口return fn.apply(null, args);}
}
//这样就可以直接调用curry了

解析:

首先,它有 2 个参数,fn 指的就是本文一开始的源处理函数 sum。currArgs 是调用 curry 时传入的参数列表,比如 (1, 2)(3) 这样的。
再看到 curry 函数内部,它会整个返回一个匿名函数。
再接下来的 let args = [].slice.call(arguments);,意思是将 arguments 数组化。arguments 是一个类数组的结构,它并不是一个真的数组,所以没法使用数组的方法。我们用了 call 的方法,就能愉快地对 args 使用数组的原生方法了。
currArgs !== undefined 的判断,是为了解决递归调用时的参数拼接。
最后,判断 args 的个数,是否与 fn (也就是 sum )的参数个数相等,相等了就可以把参数都传给 fn,进行输出;否则,继续递归调用,直到两者相等。

来测试一下封装的curry:

function sum(a, b, c) {console.log(a + b + c);
}const fn = curry(sum);fn(1, 2, 3); // 6
fn(1, 2)(3); // 6
fn(1)(2, 3); // 6
fn(1)(2)(3); // 6

5、柯里化面试考点

1、柯里化性能

1、存取arguments对象通常要比存取命名参数要慢一点
2、一些老版本的浏览器在arguments.length的实现上是相当慢的
3、使用fn.apply( … ) 和 fn.call( … )通常比直接调用fn( … ) 稍微慢点
4、创建大量嵌套作用域和闭包函数会带来花销,无论是在内存还是速度上

其实在大部分应用中,主要的性能瓶颈是在操作DOM节点上,这js的性能损耗基本是可以忽略不计的,所以curry是可以直接放心的使用。

2、代码题

// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;function add() {// 第一次执行时,定义一个数组专门用来存储所有的参数var _args = Array.prototype.slice.call(arguments);// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值var _adder = function() {_args.push(...arguments);return _adder;};// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回_adder.toString = function () {return _args.reduce(function (a, b) {return a + b;});}return _adder;
}add(1)(2)(3)                // 6
add(1, 2, 3)(4)             // 10
add(1)(2)(3)(4)(5)          // 15
add(2, 6)(1)                // 9

总结:函数的柯里化,是 Javascript 中函数式编程的一个重要概念。它返回的,是一个函数的函数。其实现方式,需要依赖参数以及递归,通过拆分参数的方式,来调用一个多参数的函数方法,以达到减少代码冗余,增加可读性的目的。
前端面试题:柯里化函数总结

参考文章:
柯里化对函数式编程有何意义?
理解函数的柯里化
详解js函数柯里化

带你看懂javascript函数柯里化(currying)相关推荐

  1. JavaScript函数柯里化详解

    目录 一.简单了解apply和call 二.什么是函数柯里化? 三.写一个公共的柯里化函数 四.创建一个灵活的柯里化函数 五.写一个可控制的执行时间的柯里化函数 一.简单了解apply和call ca ...

  2. JavaScript函数柯里化

    一.简单了解apply和call call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向. call 和 appl ...

  3. Javascript函数柯里化及其应用场景

    1.什么是柯里化 柯里化,英语:Currying,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 2.柯里化的用途 参数 ...

  4. 函数柯里化的作用一:参数复用(正则匹配案例)

    什么是函数柯里化 currying? 做题时看到 currying 这个词还挺有意思的,本意是咖喱,翻译为中文叫柯里化,是因为是以逻辑学家 Haskell Curry 命名的. arity(参数个数) ...

  5. JavaScript 专题之函数柯里化

    JavaScript 专题系列第十三篇,讲解函数柯里化以及如何实现一个 curry 函数 定义 维基百科中对柯里化 (Currying) 的定义为: In mathematics and comput ...

  6. JavaScript 中函数 柯里化风格的运用

    导语 当我第一次看见 柯里化 这个词语的时候,我也表现出一脸懵,在代码程序中,看见这种 "高大上"的一些词汇叫法的时候,下意识的会觉得这个概念很难很深奥,但是当冷静下来,去深究过后 ...

  7. 一文讲懂什么是函数柯里化,柯里化的目的及其代码实现

    柯里化(Currying) 柯里化(Currying)[1]是一种关于函数的高阶技术.它不仅被用于 JavaScript,还被用于其他编程语言. 柯里化是一种函数的转换,它是指将一个函数从可调用的 f ...

  8. js面试高频题:函数柯里化的实现(彻底弄懂)

    函数柯里化的适用场景有: 1. 参数复用 2. 延时执行 3. 提前确认 函数柯里化的核心在于:函数里面返回函数,从而做到参数复用的目的. 我们以一个js经典面试题为例开始讲解: 实现一个函数,使得满 ...

  9. 【JavaScript】函数柯里化

    文章目录 1. 什么是函数柯里化 2. 柯里化常用场景 2.1 参数复用 2.2 提前返回 2.3 延迟执行 3. 经典例题 3.1 封装通用柯里化函数 3.2 创建一个灵活的多步执行的柯里化函数 3 ...

最新文章

  1. JavaScript数据类型
  2. Phpcms V9当前栏目及所有二级栏目下内容调用标签
  3. 记一次windows的安装
  4. Oracle高级查询
  5. 杜克大学_记录链接:与杜克一起玩
  6. 计算机发展史评课议课稿,评课议课记录范文
  7. 在ListView中使用DropDownList绑定数据……好麻烦
  8. 如何在Google Play 当中使用ASO?google play aso
  9. html5微信 红包源码,微信抢红包源码和模拟demo
  10. java float 输出文本框_关于Java中float数输出时显示问题
  11. C# 正则表达式 Regex类的使用
  12. java tapestry_Tapestry简介- 转载 (转自java-cn)
  13. 入驻QQ一天就爆满,Midjourney中文版来了
  14. java程序RedisTempla往redis存key后在redis客户端获取不到key
  15. 简单的问卷调查发邮件程序
  16. 利用程序设置你的国庆专属头像
  17. (CVPR 2019)PointPillars: Fast Encoders for Object Detection From Point Clouds
  18. 【BlazePose】《BlazePose: On-device Real-time Body Pose tracking》
  19. 数理统计笔记7:分类数据分析-拟合优度检验和列联分析
  20. 用python来画出高光谱遥感影像的3D立体图

热门文章

  1. Win10必备系统优化软件:Windows 10 Manager 3.1.1
  2. 苹果带计算机记录工作和备忘录一样的软件,苹果有哪些好用的备忘录便签软件?能推荐一款吗...
  3. 关于游戏手柄连接智能硬件充当遥控器的一些问题
  4. 香港警方打击无牌照营运车辆 卧底拘捕19名司机
  5. iOS中使用特殊字体
  6. 超频到3200最佳时序_最新出炉!2020年最佳的6款内存条:游戏和强悍的台式机DDR4内存...
  7. week2:History: The First Internet - NSFNet
  8. 看过近百份简历后,才悟到简历应该怎么写【以申请硕博为例】
  9. 黑马程序员_jsp+oracle分页实现
  10. 2023-01-18 flink 11.6 时间水印 和 窗口周期的关系计算方法