之前写过一个函数Curry化的小文章

那会儿对Curry化的理解不够深,平时遇到的需要Curry化的例子也比较少,今天,重新整理这个问题

函数Curry化,其实就是将一个参数非常多的函数,在大多数参数都相同的情况下,生成一个新的参数比较少的函数的过程

但是,有一个无法解决的问题,至少我不知道该怎么办,就是只能按顺序去省略参数

上代码,先从简单的例子说起

function add( a , b , c){
    return a + b + c;
}

该方法可以计算三个数的合.

add(1,2,3);

add(1,2,4);

add(1,2,5);

....

遇到这种情况,总是写重复的参数,会不会觉得烦?不会?那看看下面的代码

function getPosition( iWidth , iHeight , iMarginBottom , iMarginRight , /* 一共有几列 */iColNum , iIndex ){
    return {
        left : iIndex % iColNum * ( iMarginRight + iWidth ),
        top : Math.floor( iIndex / iColNum ) * ( iMarginBottom + iHeight )
    }
}

假如现在需要实现一个发牌的效果,需要将每个元素都用绝对定位放到指定的位置上.

像这样.通过这个方法,只要将每个方块的各个属性和方块的索引index传递到getPosition方法里,就可以获取它应在的位置的坐标

假如现在有了一个新功能,通过点击某个按钮,可以让他们按照倒序排列

假如现在又有了一个新功能,通过点击某个按钮,可以增加新的方块

假如...

好吧,看来,getPosition()方法里的前五个参数,恐怕要多填几次了.

这时候,如果使用函数Curry化,就可以让代码看起来更清楚了,

继续使用add方法做说明,并且,将三个数相加减少到两个,

然后演示下函数Curry化的过程

代码如下:

function add( a , b ){
    if( typeof b == "undefined" ){
        return function (b){
            return a + b;
        }
    }
} 

使用方法:

var add3 = add(3)
alert( add3(4) ) 

上面的add方法中,返回了一个闭包,将第一参数a保存在了这个闭包中,同时接收一个新的参数b

这样,当我们需要大量使用add(3,??)的时候,就可以使用新的函数add3()来进行计算了.

但是,每次都这样去写,是得不偿失的,尤其是到了参数真的多起来的时候,更是愚蠢,因此,需要封装一个方法,实现Curry化

首先,需要补充点小知识点

1.function里的argumens,并不是一个真正的数组

2.arrObject.slice(start,/*optional*/end) 方法, 可以返回一个数组里[start,end)部分的元素,当只填写了start参数时,会获取从start开始一直到结尾的元素,这个方法不会改变原来的数组

3.Array.prototype.slice  可以将arguments转化为一个真正的数组.

知识点3的测试代码如下

var mySlice = Array.prototype.slice;function test(a,b,c,d){
    //通过mySlice可以将arguments转换为一个真正的数组
    console.dir(mySlice.call(arguments))
}
test(1,2,3,4)

控制台显示Array[4];

最终函数Curry化代码如下

function curry(fn/*,arg1,arg2,arg3,......*/){
    var mySlice = Array.prototype.slice;
    var save_args = mySlice.call(arguments,1)
    return function (){
        var newArgs = mySlice.call(arguments);
        var args = save_args.concat(newArgs);
        return fn.apply(null,args)
    }
}

从原理到中间利用的知识点,已经说的比较清楚了,不再赘述.

附加测试代码:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
*{ margin:0; padding:0;}
ul{ list-style:none;}
li{ position:absolute; width:100px; height:100px; background-color:#000;}
</style>
<script>
function getPosition( iWidth , iHeight , iMarginBottom , iMarginRight , /* 一共有几列 */iColNum , iIndex ){
    return {
        left : iIndex % iColNum * ( iMarginRight + iWidth ),
        top : Math.floor( iIndex / iColNum ) * ( iMarginBottom + iHeight )
    }
}
function curry(fn/*,arg1,arg2,arg3,......*/){
    var mySlice = Array.prototype.slice;
    var save_args = mySlice.call(arguments,1)
    return function (){
        var newArgs = mySlice.call(arguments);
        var args = save_args.concat(newArgs);
        return fn.apply(null,args)
    }
}
window.onload = function (){
    var oUl = document.getElementById("ul");
    var aLis = oUl.getElementsByTagName("li");

    var iWidth = 100;
    var iHeight = 100;
    var iMargin = 10;

    var iColNum = 3;

    var newGetPosition = curry( getPosition , iWidth , iHeight , iMargin , iMargin , iColNum );

    for( var i=0; i<aLis.length; i++ ){
        //var p = getPosition( iWidth , iHeight , iMargin , iMargin , iColNum , i )
        var p = newGetPosition(i)
        aLis[i].style.top = p.top + "px";
        aLis[i].style.left = p.left + "px";
    }
}
</script>

</head>

<body>
<ul id="ul">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
</body>
</html>

到这里了,睡觉去zzzZZZZ....

函数Curry化的更多相关文章

  1. 转:python中函数curry化

    1 柯里化(Currying) 一个函数有多个参数,我们希望能固定其中几个参数的值. from functools import partial def foo(a,b,c): return a+b+ ...

  2. Curry化函数

    <script> function fn(){ var i, rult = 0, len = arguments.length; for (i=0;i<len ;i++ ) { ru ...

  3. ♫【模式】Curry化

    /** * 当发现正在调用同一个函数,并且传递的参数绝大多数都是相同的, * 那么该函数可能是用于Curry化的一个很好的候选参数 */ ;(function() { function add(x, ...

  4. scala学习手记25 - Curry化

    curry翻译为中文就是咖喱.意为使用curry可以让代码更有味道. scala里的curry化可以把函数从接收多个参数转换成接收多个参数列表.也就是说我们要编写的函数不是只有一个参数列表,这个参数列 ...

  5. React 应用设计之道 - curry 化妙用

    使用 React 开发应用,给予了前端工程师无限"组合拼装"快感.但在此基础上,组件如何划分,数据如何流转等应用设计都决定了代码层面的美感和强健性. 同时,在 React 世界里提 ...

  6. JavaScript基础Curry化(021)

    时候我们希望函数可以分步接受参数,并在所有参数都到位后得到执行结果.为了实现这种机制,我们先了解函数在Javascript中的应用过程: 1. 函数的“应用”(Function Application ...

  7. (MTT)连续能量函数最小化方法

    (MTT)连续能量函数最小化方法 Multitarget tracking Multi-object tracking 连续能量函数 读"A.Milan,S. Roth, K. Schind ...

  8. Scalaz(3)- 基础篇:函数概括化-Generalizing Functions

    Scalaz是个通用的函数式编程组件库.它提供的类型.函数组件都必须具有高度的概括性才能同时支持不同数据类型的操作.可以说,scalaz提供了一整套所有编程人员都需要的具有高度概括性的通用函数,它是通 ...

  9. vue render函数 函数组件化

    之前创建的锚点标题组件是比较简单,没有管理或者监听任何传递给他的状态,也没有生命周期方法,它只是一个接受参数的函数 在这个例子中,我们标记组件为functional,这意味它是无状态(没有data), ...

随机推荐

  1. python返回值与局部全局变量

    Python 2.7.10 (default, Oct 14 2015, 16:09:02) [GCC 5.2.1 20151010] on linux2 Type "copyright&q ...

  2. Python的由来

    Python的由来 Python这门语言是由C开发而来. C语言: 代码编译得到 机器码 ,机器码在处理器上直接执行,每一条指令控制CPU工作 其他语言: 代码编译得到 字节码 ,虚拟机执行字节码并转 ...

  3. Python基本数据类型

    一.整数 int(整形) 在32位机器上,整数的位数为32位,取值范围为-2**31~2**1-1,即-2147483648-2147483647 在64位系统上,整数的位数为64位,取值范围为-2* ...

  4. Win10环境下安装Vmware+Ubuntu14 注意点

    下载相关软件正常安装完成后可能会碰到以下两个问题,这里备注一下,备用 1.Ubuntu的root密码设置 2.Vmware网络连接设成桥接之后,Win10可以ping通Ubuntu,但Ubuntu无法 ...

  5. ecshop调用后台指定广告位下所有广告循环

    ecshop本身的广告调用规则是:对某个广告位下的广告列表随机显示其中一条. 而我们有时需要将某个广告位下的所有广告全部显示出来,那么如何处理呢,下面就自己做了一个函数: \includes\lib_ ...

  6. myecplise 中文乱码

    一.设置新建常见文件的默认编码格式,也就是文件保存的格式. 在不对MyEclipse进行设置的时候,默认保存文件的编码,一般跟简体中文操作系统(如windows2000,windowsXP)的编码一致 ...

  7. C语言 链表排序

    #include <stdio.h> #include <stdlib.h> #include <assert.h> typedef struct node{ in ...

  8. Vim基础操作

    在正式使用Vim之前,先来点开胃菜,学习下Vim中一些常用的命令,有了这些基本命令,才能让我们使用Vim更加得心应手,加快工作的效率~ 注意:接下来将要介绍的命令主要是用在Vim的Normal模式下. ...

  9. 解决java.lang.InstantiationError: sun.net.ftp.FtpClient

    换用jdk1.6 .如果是放容器里的,也把容器的jdk换成1.6

  10. zoj 3820(2014牡丹江现场赛B题)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5374 思路:题目的意思是求树上的两点,使得树上其余的点到其中一个点的 ...