柯里化与反柯里化 最近在看一本书《JavaScript函数式编程》 里边提到了一个名词,柯里化(currying),阅读后发现在日常开发中经常会用到柯里化函数。 以及还有他的反义词反柯里化(unCurrying) 柯里化被称为部分计算函数,也就是会固定一部分参数,然后返回一个接收剩余参数的函数。目的是为了缩小适用范围,创建一个针对性更强的函数。 , '4'].map(curry(parseInt)) // => 1, 2, 3, 4 缩小适用范围,创建一个针对性更强的函数 反柯里化unCurrying 虽说名字叫反柯里化。。 console.log(+a(2)(3)) // 6 这里是一个实现的方案:https://github.com/Jiasm/notebook/blob/master/currying.js 一个柯里化实现的变体 其实柯里化还分为了向右柯里化、向左柯里化(大概就是preArgs和args的调用顺序问题了) 用函数构建出新的函数,将函数组合在一起,这个是贯穿这本书的一个理念,在现在大量的面向对象编程开发中,能够看到这么一本书
前言 柯里化,可以理解为提前接收部分参数,延迟执行,不立即输出结果,而是返回一个接受剩余参数的函数。因为这样的特性,也被称为部分计算函数。柯里化,是一个逐步接收参数的过程。 反柯里化,是一个泛型化的过程。它使得被反柯里化的函数,可以接收更多参数。目的是创建一个更普适性的函数,可以被不同的对象使用。有鸠占鹊巢的效果。 一、柯里化 1.1 例子 实现 add(1)(2, 3)(4)() = 10 的效果 依题意,有两个关键点要注意: 传入参数时,代码不执行输出结果,而是先记忆起来 当传入空的参数时,代表可以进行真正的运算 综合上述思考,就可以得到以下完整的柯里化函数。 由此可以得出,反柯里化后,第一个参数,是用来指定this指向的。
柯里化与反柯里化 最近在看一本书《JavaScript函数式编程》 里边提到了一个名词,柯里化(currying),阅读后发现在日常开发中经常会用到柯里化函数。 以及还有他的反义词反柯里化(unCurrying) 柯里化被称为部分计算函数,也就是会固定一部分参数,然后返回一个接收剩余参数的函数。目的是为了缩小适用范围,创建一个针对性更强的函数。 , '4'].map(curry(parseInt)) // => 1, 2, 3, 4 缩小适用范围,创建一个针对性更强的函数 反柯里化unCurrying 虽说名字叫反柯里化。。 console.log(+a(2)(3)) // 6 这里是一个实现的方案:https://github.com/Jiasm/notebook/blob/master/currying.js 一个柯里化实现的变体 其实柯里化还分为了向右柯里化、向左柯里化(大概就是preArgs和args的调用顺序问题了) 用函数构建出新的函数,将函数组合在一起,这个是贯穿这本书的一个理念,在现在大量的面向对象编程开发中,能够看到这么一本书
柯里化,是一个逐步接收参数的过程。在接下来的剖析中,你会深刻体会到这一点。 反柯里化,是一个泛型化的过程。它使得被反柯里化的函数,可以接收更多参数。目的是创建一个更普适性的函数,可以被不同的对象使用。 一、柯里化 1.1 例子 实现 add(1)(2, 3)(4)() = 10 的效果 依题意,有两个关键点要注意: - 传入参数时,代码不执行输出结果,而是先记忆起来 - 当传入空的参数时,代表可以进行真正的运算 综合上述思考,就可以得到以下完整的柯里化函数。 而实现这一步骤的过程,就需要增加反柯里化后的objShow方法参数。 由此可以得出,反柯里化后,第一个参数,是用来指定this指向的。
本文旨在介绍函数式编程中柯里化的概念,以及在JavaScript中应该何时使用它。本文将首先解释什么是柯里化,然后展示它在函数式编程背景下的用处。 什么是柯里化柯里化是指函数永远只接受一个参数,如果需要处理多个参数,则返回另一个函数来接收单一的参数。相比之下,常规非柯里化函数可以接受多个参数。 相同函数的柯里化版本如下所示:const addCurried = x => y => x + yconsole.log( addCurried(2)(3) // 2 + 3) // prints 5 (4)(5) // 1 + 2 + 3 + 4 + 5) // prints 15由于柯里化函数的工作方式,我们可以进行称为部分应用的操作。 什么时候使用柯里化函数呢?函数柯里化在我们的普通的函数时是没有什么优势的,他的真正优势在于组合使用,只有在组合使用时才它能真正发挥了作用。
柯里化 什么是柯里化 Currying(果然是满满的英译中的既视感),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 function foo(x, y) { return x + y; } // 柯里化 function bar(x) { return function(y) { return x + y; } } bar(1)(2); // 3 看到上面这个例子,我们明白柯里化其实就是先用一个函数接受一个参数,然后再返回一个函数接受另一个参数,最后返回计算结果。 通过柯里化就可以达到复用第一个参数。
bug收集:专门解决与收集bug的网站 网址:www.bugshouji.com 柯里化,其本质就是高级函数的一种应用,那费这么大劲封装,到底有什么用处呢? 封装一些dom操作可以说再常见不过,上面第一种写法也是比较常见,但是我们看看第二种写法,它相对一第一种写法就是自执行然后返回一个新的函数,这样其实就是提前确定了会走哪一个方法,避免每次都进行判断 03 好处3: 说了这几点好处之后,发现还有个问题,难道每次使用Currying都要对底层函数去做修改 04 柯里化:简单封装 // 初步封装 var currying = function(fn) { // 但是好像还有些什么缺陷,这样返回的话其实只能多扩展一个参数,currying(a)(b)(c)这样的话,貌似就不支持了(不支持多参数调用),一般这种情况都会想到使用递归再进行封装一层 05 柯里化:完美封装 return fn.apply(this, _args); } } 这边其实是在初步的基础上,加上了递归的调用,只要参数个数小于最初的fn.length,就会继续执行递归 关于,柯里化的文章就介绍到这里
柯里化其实也是函数式编程的思想。下面来举例说明什么是柯里化呢? 提高维护性以及降低代码的重复性 二、柯里化的场景 1、比如我们在求和中,以一定的数字为基数进行累加的时候,就用到了函数柯里化。当然函数柯里化感觉上是把简答的问题复杂化了,其实不然。 是不是可以进行抽离呢,当然了,函数柯里化就可以完美的解决这个。 3)) console.log(" ~ file: preview.html ~ line 81 ~ selfSum(1, 2)(3)", selfSum(1)(2)(3)) 四、柯里化在其他库的应用 1、我们常用的 Redux,里面其实也用到了柯里化。
在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。 函数柯里化 函数柯里化指的是将能够接收多个参数的函数转化为接收单一参数的函数,并且返回接收余下参数且返回结果的新函数的技术。 ); // 6 add(1)(2)(3); // 6 上面的 add 函数就是一个被柯里化的函数,这个函数接收三个参数,但是调用时参数可以传一个或两个或一次直接传三个,而最终返回的值是一样的。 我们可以定义一个函数,这个函数的参数是一个函数,而返回一个新的函数,这个函数就是被柯里化后的函数。 这个包装函数就可以在第一次就知道被包装的函数有几个参数,在适当的时候返回结果。 // 那就执行被柯里化的函数 return fn.apply(this,args); }else{ // 否则继续返回一个新的函数
source=cloudtencent 什么是函数柯里化? 函数柯里化(Haskell Brooks Curry),当一个函数有多个参数的时候先传递一部分参数并且调用它(这部分参数后续不会进行改变),然后返回一个新的函数接收剩余的参数并返回结果。 总结 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数 这是一种对函数参数的 "缓存" 让函数变的更灵活,让函数的粒度更小 基础案例# 案例 1 function checkAge = checkAge(20) console.log(checkAge18(19)) // true console.log(checkAge20(19)) // false 案例 2 // 封装柯里化函数 = fn2(3) // 返回结果 6
柯里化的表现:把原先接受多个参数的函数转化为只接受一个参数的函数。 柯里化带来的作用: 参数复用 延迟执行 提前返回 function sum(x, y, z) { return x + y + z; } // 通用的柯里化函数 function curry(func / 最终执行初次传入的函数,并将所有参数丢给它 } } }; } let curriedSum = curry(sum); alert( curriedSum(1, 2, 3) (1)(2)(3) ); // 6, full currying 当 curry(sum)执行后返回一个函数,以 curriedSum(1)(2,3) 为例,实际就是curried(1) function } } }; curried(1) // 第一个参数被执行 --> 发现参数个数小于最开始定义的 sum 函数的参数 --> 再返回一个函数,此时这个函数执行的入参为 (2,3)
(x + y) } 现在我们直接实现一个被柯里化的 add 函数,该函数名为 curriedAdd,则根据上面的定义,curriedAdd 需要满足以下条件: curriedAdd(1)(3) === 所以我们可以通过递归来将柯里化返回的函数也自动柯里化。 三、柯里化的应用 1、参数复用 固定不变的参数,实现参数复用是柯里化的主要用途之一: var increment = curriedAdd(1) increment(2) === 3 // true // => [1, 2, 3] ② 为函数式编程而生 柯里化是为函数式而生的东西,应运着有一整套函数式编程的东西,纯函数、compose、container 等等。 3、柯里化生于函数式编程,也陷于函数式编程。
一、定义把一个接受多个参数的函数变为接受一个参数的函数,同时返回剩余参数且返回结果的新函数二、应用提取公共柯里化函数,接受至少两个参数,一个是处理函数,其余参数是处理函数所需的参数,以下代码为校验的方法 1[3|4|5|6|7|8][0-9]\d{8}$/; return this.currie(this.verify, reg)(tel); }}export default singleton 读取arguments往往比直接读取命名参数要稍微慢,尤其老版本浏览器则很明显四、面试真题实现以下这么sum函数,满足一下需求sum(1, 2) == 3sum(1)(2) == 3sum(1)(2, 3) == 6sum(1)(2)(3)(4) == 10分析如下:1. 支持链式调用,需返回function3.
后面几部分将结合实际应用场景介绍高阶函数的应用,本节先来聊聊函数柯里化,通过介绍其定义、比较常见的三种柯里化应用、并在最后实现一个通用的 currying 函数,带你认识完整的函数柯里化。 柯里化 定义 函数柯里化又叫部分求值,维基百科中对柯里化 (Currying) 的定义为: 在数学和计算机科学中,柯里化是一种将使用多个参数的函数转换成一系列使用一个参数的函数,并且返回接受余下的参数而且返回结果的新函数的技术 我们看下 bind 模拟实现,其本身就是一种柯里化,我们在最后的实现部分会发现,bind 的模拟实现和柯理化函数的实现,其核心代码都是一致的。 // 3 所以在柯里化的场景中,不建议使用 ES6 的函数参数默认值。 小结 我们通过定义认识了什么是柯里化函数,并且介绍了三种实际的应用场景:延迟计算、动态创建函数、参数复用,然后实现了强大的通用化 currying 函数,不过更像是柯里化 (currying) 和偏函数
在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 高阶函数和柯里化是函数式编程的特性。 随着函数在Java 8中变成一等公民,自然而然会产生柯里化。 柯里化的链式调用的确用起来很爽。柯里化也可以延迟加载一个函数。 除此以外,柯里化在很多时候简化了函数式编程的复杂性,使编程更加优雅。当然,在团队中使用的话,也需要充分考虑到团队中其他成员是否接受。 总结 Java 8虽然是OO+FP的结合,能够支持lambda表达式、高阶函数、闭包等,但是并没有提供函数柯里化与偏函数(函数部分调用)的语法糖,当然想要使用的话肯定是可以模拟出来。
下面来一起看看究竟什么是函数柯里化 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第一个参数)的函数,并返回接受剩余的参数而且返回结果的新函数的技术。 ,上面代码虽然简单的实现了柯里化的基本操作,但是对于参数不确定的情况是处理不了的;所以存在着函数参数的局限性;不过我们从上面的代码中基本可以知道函数柯里化是个啥意思了;就是一个函数调用的时候只允许传入一个参数 (); //也可以一次性传入多个参数 s(1,2,3); console.log(s()); JS函数柯里化的优点: 1.可以延迟计算,即如果调用柯里化函数传入参数是不调用的,会将参数添加到数组中存储 ,等到没有参数传入的时候进行调用; 2.参数复用,当在多次调用同一个函数,并且传递的参数绝大多数是相同的,那么该函数可能是一个很好的柯里化候选。 世间万物相对,有因必有果,当然了,有柯里化必然有反柯里化; 反柯里化(uncurrying) 从字面意思上来讲就是跟柯里化的意思相反;其实真正的反柯里化的作用是扩大适用范围,就是说当我们调用某个方法的时候
一、什么是函数柯里化 柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。 说的啥玩意啊? 是不是一脸懵逼~ 接下来咱们用一个经典的面试题讲解下:实现 add(1)(2)(3) 求和 第一步:接收三个参数 function add (a, b, c) { return a + b + c } // add(1, 2, 3) 第二步:接收两个参数 function add (a, b) { return function (c) { return a + b + c } } // add(1,2)(3) 到这是不是有点眉头了? 但是假如面试官让你用一个函数同时支持 add(1,2,3), add(1,2)(3), add(1)(2)(3)怎么办? 先补充个概念,下面要用到 --- 函数的长度是啥?
柯里化 指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。 新的函数返回一个以原有第二个参数为参数的函数 z = f(x, y) 转换成 z = f(x)(y)的形式 举例: """ 将加法函数柯里化 """ def add(x, y): return : return x + y return _add foo = add(4) print(foo(5)) print(add(4)(5)) 通过嵌套函数就可以把函数转换成柯里化函数
柯里化 当函数有多个参数的时候我们对函数进行改造并返回一个函数,只传入部分参数,只到函数执行完毕f(1,2,3) ==> f(1)(2)(3) 使用柯里化解决代码中的硬编码问题 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数 返回值: 柯里化后的函数 //lodash 中的 curry 基本使用 const _ = require("lodash"); //一个参数叫一元函数 2个叫二元函数 3个叫三元函数 function ); console.log(curried(1)(2)(3)); console.log(curried(1)(2,3)); console.log(curried(1,2)(3)); //柯里化案例 (curried(1)(2)(3)); console.log(curried(1)(2,3)); console.log(curried(1,2)(3)); //柯里化案例 //案例1 判断一个字符串中有没有空白字符 return func(...args) } } 柯里化总结: 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数 这是一种对函数参数的’缓存’ 让函数变的更灵活
_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的所有剩余参数 add(1, 2, 3); _add(1)(2)(3); 当然,靠眼力封装的柯里化函数自由度偏低,柯里化通用式具备更加强大的能力。因此我们需要知道如何去封装这样一个柯里化的通用式。 当情况变得多变,柯里化依然能够应付自如。 虽然柯里化确实在一定程度上将问题复杂化了,也让代码更加不容易理解,但是柯里化在面对复杂情况下的灵活性却让我们不得不爱。 当然也并不建议在任何情况下以炫技为目的的去使用柯里化,在柯里化的实现中,我们知道柯里化虽然具有了更多的自由度,但同时柯里化通用式里调用了arguments对象,使用了递归与闭包,因此柯里化的自由度是以牺牲了一定的性能为代价换来的 只有在情况变得复杂时,才是柯里化大显身手的时候。 额外知识补充 无限参数的柯里化。 该部分内容可忽略 在前端面试中,你可能会遇到这样一个涉及到柯里化的题目。