就像最早听到斐波拉切数列一样,第一次听到柯里化我也是懵逼的
前言
本文旨在让大家简单理解柯里化和反柯里化,这里不做深入探究,只求能带大家装逼就好,看完还不懂你砍我。
我们先来简单了解一下他们的作用。
柯里化又称部分求值,字面意思就是不会立刻求值,而是到了需要的时候再去求值。如果看的懵逼,没事,看完整篇文章再回过头来看这里你就会豁然开朗。
反柯里化的作用是,当我们调用某个方法,不用考虑这个对象在被设计时,是否拥有这个方法,只要这个方法适用于它,我们就可以对这个对象使用它。
柯里化(curring)
我们有这样一个场景,记录程序员一个月的加班总时间,那么好,我们首先要做的是记录程序员每天加班的时间,然后把一个月中每天的加班的时间相加,就得到了一个月的加班总时间。
但问题来了,我们有很多种方法可以实现它,比如最简单的:
|
|
每次传入加班时间都进行累加,这样当然没问题,但你知道,如果数据量很大的情况下,这样会大大牺牲性能。
那怎么办?这就是柯里化要解决的问题。
其实我们不必每天都计算加班时间,只需要保存好每天的加班时间,在月底时计算这个月总共的加班时间,所以,其实只需要在月底计算一次就行。
下面的overtime函数还不是一个柯里化函数的完整实现,但可以帮助我们了解其核心思想:
|
|
柯里化的核心思想就是这样,看到这里你肯定已经懂了,至于真正的柯里化函数,网上有很多,大家可以去Google一下。
反柯里化(uncurring)
反柯里化的的作用已经在前言说过了,这里讲下它的由来。
2011年JavaScript之父Brendan Eich发表了一篇Twitter,提出了反柯里化这个思想,下面这段代码是反柯里化的实现方式之一:
|
|
我们先来看看上面这段代码有什么作用。
我们要把Array.prototype.push方法转换成一个通用的push函数,只需要这样做:
|
|
arguments
本来是没有push
方法的,通常,我们都需要用Array.prototype.push.call
来实现push
方法,但现在,直接调用push
函数,既简洁又意图明了。
就和前言写的那样,我们不用考虑对象是否拥有这个方法,只要它适用于这个方法,那就可以使用这个方法(类似于鸭子类型)。
我们来分析一下调用Array.prototype.push.uncurring()
这句代码时,发生了什么事情:
|
|
看到这里你应该对柯里化和反柯里化有了一个初步的认识了,但要熟练的运用在开发中,还需要我们更深入的去了解它们内在的含义。
本文参考:
本文作者:余震(Freak)
本文出处:Rockjins Blog
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN许可协议。转载请注明出处!