转载请注明出处:http://www.cnblogs.com/shamoyuu/p/currying.html

什么是js函数的currying /柯里化?

说到js的柯里化,相信很多朋友都会头大。或者不是很清楚。我今天简单的给大家介绍一下。

我用一句话总结函数柯里化,js柯里化是逐步传参,逐步缩小函数的适用范围,逐步求解的过程

可能对这句话你不是很清楚,那么,我们来看个案例,简单说明一下:

需求:我们写一个函数,将函数的几个参数相加,返回结果!那我们写的函数如下

var concat3Words = function (a, b, c) {
    return a+b+c;
};

函数柯里化呢?是分部求解,先传一个a参数,再传一个b参数,再传一个c参数,最后将这三个参数相加!

var concat3WordsCurrying = function(a) {
    return function (b) {
        return function (c) {
            return a+b+c;
        };
    };
};

我们看输出结果:

console.log(concat3Words("foo ","bar ","baza"));            // foo bar baza
console.log(concat3WordsCurrying("foo "));                  // [Function]
console.log(concat3WordsCurrying("foo ")("bar ")("baza"));  // foo bar baza 函数链式调用

柯里化案例

上面的需求我们稍微变一下。现在我们更进一步,如果要求可传递的参数不止3个,可以传任意多个参数,当不传参数时输出结果?那现在我们用柯里化来简单的实现一下:

var adder = function () {
    var _args = [];
    return function () {
        ) {
            return _args.reduce(function (a, b) {
                return a + b;
            });
        }
        [].push.apply(_args, [].slice.call(arguments));
        return arguments.callee;
    }
};
var sum = adder();

console.log(sum);     // Function

sum(,)();    // 调用形式灵活,一次调用可输入一个或者多个参数,并且支持链式调用
sum();
console.log(sum());   // 1000 (加总计算) 

上面 adder是柯里化了的函数,它返回一个新的函数,新的函数接收可分批次接受新的参数,延迟到最后一次计算。我们可以任意传入参数,当不传参数的时候,输出计算结果!

基础知识普及之arguments

看到上面的柯里化实现,可能有的朋友会有点晕,其实上面也没有什么新的知识,假如你看过我之前写的文章,相信能够理解!apply,call之前都有介绍。前端干货中的第四条,也有提及!唯独arguments前面文章没有介绍。

arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。arguments非常类似Array,但实际上又不是一个Array实例。

我们看一下下面的例子:

function f(a, b, c){
    alert(arguments.length);   // result: "2"
    a = ;
    alert(arguments[]);       // result: "100"
    arguments[] = "haorooms";
    alert(a);                  // result: "haorooms"
    alert(c);                  // result: "undefined"
    c = ;
    alert(arguments[]);       // result: "undefined"
}

f(, );

我们通常用

[].slice.call(arguments, )

将传入参数转为数组。slice是js的一个函数,关于其用法,不会的去查一下!上面的写法相当于Array.prototype.slice.call(arguments, 1);

另外,arguments对象中有一个非常有用的属性:callee。arguments.callee返回此arguments对象所在的当前函数引用。在使用函数递归调用时推荐使用arguments.callee代替函数名本身。arguments就介绍到这里!

通用的柯里化函数

下面这个是通用的柯里化函数

var currying = function (fn) {
    var _args = [];
    return function () {
        ) {
            return fn.apply(this, _args);
        }
        Array.prototype.push.apply(_args, [].slice.call(arguments));
        return arguments.callee;
    }
};

我们可以通过如下函数简单应用一下柯里化:

var multi=function () {
    ;
    , c; c = arguments[i++];) {
        total += c;
    }
    return total;
};

var sum = currying(multi);  

sum(,)();
sum();
console.log(sum());     // 1000  (空白调用时才真正计算)

增加适用性的柯里化

上面我的介绍的是柯里化延迟执行,缩小范围!还有一种是增加了函数的适用性,但同时也降低了函数的适用范围。其通用写法如下:

function currying(fn) {
    var slice = Array.prototype.slice,
    __args = slice.call(arguments, );
    return function () {
        var __inargs = slice.call(arguments);
        return fn.apply(null, __args.concat(__inargs));
    };
}

例如:

function square(i) {
    return i * i;
}
function map(handeler, list) {
    return list.map(handeler);
}
// 数组的每一项平方
map(square, [, , , , ]);
map(square, [, , , , ]);
map(square, [, , , , ]);

例子中,创建了一个map通用函数,用于适应不同的应用场景。显然,通用性不用怀疑。同时,例子中重复传入了相同的处理函数:square。

柯里化改造:

function square(i) {
    return i * i;
}
function map(handeler, list) {
    return list.map(handeler);
}
var mapSQ = currying(map, square);
mapSQ([, , , , ]);
mapSQ([, , , , ]);
mapSQ([, , , , ]);

Function.prototype.bind 方法也是柯里化应用

与 call/apply 方法直接执行不同,bind 方法 将第一个参数设置为函数执行的上下文,其他参数依次传递给调用方法(函数的主体本身不执行,可以看成是延迟执行),并动态创建返回一个新的函数, 这符合柯里化特点。

};
var bar = function () {
    console.log(this.x);
}.bind(foo); // 绑定
bar();

完结,散花

JavaScript函数的柯里化(currying)的更多相关文章

  1. js高阶函数--判断数据类型、函数胡柯里化;

    一.判断数据类型: 常见的判断有typeof.instanceof. constructor. prototype,先来看typeof: var a = "hello world" ...

  2. 浅谈JavaScript中的柯里化函数

    首先,不可避免的要引经据典啦,什么是柯里化函数呢(from baidu): 在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返 ...

  3. JavaScript函数式编程(纯函数、柯里化以及组合函数)

    JavaScript函数式编程(纯函数.柯里化以及组合函数) 前言 函数式编程(Functional Programming),又称为泛函编程,是一种编程范式.早在很久以前就提出了函数式编程这个概念了 ...

  4. Swift函数柯里化(Currying)简谈

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面简单说说Swift语言中的函数柯里化.简单的说就是把接收多 ...

  5. JS 函数的柯里化与反柯里化

    ===================================== 函数的柯里化与反柯里化 ===================================== [这是一篇比较久之前的总 ...

  6. 关于arguments对象以及函数的柯里化;

    1.arguments对象 Arguments是个类似数组但不是数组的对象,说他类似数组是因为其具备数组相同的访问性质及方式,能够由arguments[n]来访问对应的单个参数的值,并拥有数组长度属性 ...

  7. JS中的柯里化(currying)

    何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参 ...

  8. JS中的柯里化(currying) 转载自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]

    JS中的柯里化(currying) by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpr ...

  9. Python进阶1---高阶函数、柯里化

    高阶函数 不相等  自定义sort函数 内建函数--高阶函数 #sort函数 def sort2(lst,key = None,reverse = False): res = [] if key is ...

随机推荐

  1. java对象引用-要掌握的细节2

    目的:加深对java引用变量的理解,避免数据的处理的偏差. 问题: 1.一个集合List ,将新建Student对象stu放入List之后,再给stu的成员变量例如id,name赋值.此时List中的 ...

  2. OpenStreetMap数据清洗(SQL&MonogoDB版本)

    目标:通过网上下载的OpenStreetMap.xml数据格式,将该文件的格式进行统计,清洗,并导出成CSV格式的文件,最后倒入到SQLite中 本案例中所需的包 import csv import ...

  3. SQLServer2008修改sa密码的方法与SQL server 2008数据库的备份与还原

    sa密码的修改转载自:http://blog.csdn.net/templar1000/article/details/20211191 SQL server 2008数据库的备份与还原转自 :htt ...

  4. 浏览器中页面的visibility状态及变化监听

    需求 在浏览器中播放视频,当用户进行页面切换操作时.需要根据视频播放页是否处于可见状态,来控制视频的暂停及重新播放. 相关文档 参考MDN中,关于页面的可见性相关的API说明.https://deve ...

  5. centos 6.3安装ssh

    centos 6.3安装ssh   安装ssh服务器端软件 yum install openssh-server   安装ssh客户端软件   yum install openssh-clients ...

  6. ABP官方文档翻译 3.2 值对象

    值对象 介绍 值对象基类 最佳实践 介绍 "展现领域描述性层面且没有概念性身份的对象称之为值对象."(Eric Evans). 和实体相反,实体有身份标示(Id),值对象没有身份标 ...

  7. DG环境的日常巡检

    DG环境的日常巡检 目录 1.DG环境的日常巡检4 1.1.主库环境检查4 1.1.1.主库实例启动状态检查4 1.1.2.主库启动模式检查4 1.1.3.主库DG环境的保护模式检查4 1.1.4.主 ...

  8. [一个脑洞] Candy?'s 不饱和度

    update 2017.7.10 Candy?'s 不饱和度 题目背景 化学老师让同学们出题!昌老师担任有机组组长! Candy?出了一道数不饱和度的题目,昌老师不会做所以拒绝接受!!! 于是Cand ...

  9. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  10. 安装Spring Tool Suite(STS)

    JAVA开发工具中,常用工具就是Eclipse,IntelliJ IDEA. 现在使用spring boot&cloud框架进行开发的时候,虽然可以使用上面两个工具,但都未必就真的量身定制,I ...