什么是柯里化?
科里化是把一个多参数函数转化为一个嵌套的一元函数的过程。(简单的说就是将函数的参数,变为多次入参)const curry = (fn, ...args) => fn.length <= args.length ? fn(...args) : curry.bind(null, fn, ...args);// 想要看懂上面这个函数,重点在于全面理解bind的用法。// 思路倒是很简单,就是在参数未搜集完善之前,通过bind来实现参数搜集,// 当搜集完成时,就可以执行原函数了。const add = (x, y) => x + y;const curryadd = curry(add);curryadd(4)(4); // 8
关于bind的认知
bind 和 call / apply 很相似,都可以改变 this 的指向,也都可以传递参数。但还是有一些区别:1)bind不会立即执行函数,而是返回一个新函数。譬如在 React 中我们经常用 bind 将函数的 this 指向组件本身:
export default class ClickOutside extends Component { constructor(props) { super(props) this.getContainer = this.getContainer.bind(this) } getContainer(ref) { this.container = ref }}
2)除了 this 以外的参数,会把原函数的参数位给占领(扰乱王?鸠占鹊巢?小三上位?),也就是预设值绑定(赋值):
// demo1: 演示预设绑定 x 和 y 的参数const add = (x, y, z) => x + y + z;add.bind(null, 1, 2)(3) // => 6 , 等价于 add(1, 2, 3) // demo2: 演示多次bindconst add = (x, y) => x + y;const myadd = add.bind(null, 1).bind(null, 2)myadd() // => 3 , 等价于 add(1, 2) // demo3: 和...args这种数组解构结合使用时可别懵了 O(∩_∩)O哈哈~const add = (...args) => console.log(args, args.length);const myadd = add.bind(null, 1).bind(null, 2).bind(null, 3).bind(null, 4).bind(null, 5)myadd() // => [1, 2, 3, 4, 5] 5
这种特性实际上和 偏应用 很相似,区别仅仅在于偏应用不需要关注 this 的绑定。
偏应用的目的只有一个,那就是通过预设值减少函数的参数位,达到简化函数、惰性函数、可重用函数等目的。