简单理解柯里化函数
背景
Ant Desgin 用多了,想换种口味。所以最近改用 Material UI 开发页面。其中用到 Switch 组件时,在官方 demo 中发现一个箭头函数的写法:
1 | const handleChange = name => event => { |
作为一个「兼职」的前端开发,第一次看到双箭头函数的写法,自然要探个究竟。
定义
这种方式的写法究竟是什么呢?其实标题已经给出答案,官方定义其为柯里化函数:
在计算机科学中,柯里化(英語:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
用通俗一点的解释就是:一个多形参的函数在柯里化后变成每次调用时只处理一个参数。
举个栗子,假如给定一个函数 foo,它需要同时接收三个整型参数 a、b、c,并对它们求和。
那么函数 foo 的柯里化版本就是调用方式从原来的foo(a,b,c)
变成了foo(a)(b)(c)
。这是高阶函数的一种应用,也是函数式编程的重要思想。最后一次函数调用才真正返回结果值,中间的过程的调用返回值都是函数。
当然,可以用现在流行的箭头函数写法解决「回调地狱」,改造上面的表述:
1 | function foo(a, b, c) { |
好处
假如 Switch 组件的变更函数不使用柯里化方式,调用方式将会是什么样呢?
1 | // 不需要传入 name 时 |
通过上面的例子可以看到,假如不需要传入多余的参数,可以直接绑定函数名。如果需要传入自定义参数,那么非柯里化的函数在绑定时无法直接写成函数调用的形式,必须通过匿名的箭头函数包裹我们的调用函数。所以柯里化后的写法上可以直接使用直觉上的函数绑定形式。
加料区
另外这个代码中可以关注到的一个小知识点是: 变量作为字符串传入时,可以通过括号包裹后变成 JSON 字符串的 key 值,否则直接填入变量名的话,key 就是其字面值了。
1 | function handleChange(name) { |
参考资料
https://stackoverflow.com/questions/36314/what-is-currying
https://zh.wikipedia.org/zh/%E6%9F%AF%E9%87%8C%E5%8C%96
https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983