转载请注明出处: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. Selenium+java+idea的安装与配置

    当前操作系统:Windows10pro x64 一.安装JDK 1.到jdk官网下载一个对应当前系统的安装包(Selenium仅支持JDK1.8及以上版本) 网址:http://www.oracle. ...

  2. Linux服务器删除乱码文件和文件夹的方法

    Linux服务器删除乱码文件和文件夹的方法 首页进入乱码文件所在文件夹由于php大势所趋,所以接触Linux服务器的机会越来越多.不同于Windows服务器,Linux服务器只支持数字.英文等字符,对 ...

  3. 重定向stdin stdout stderr |

    在Linux下,当一个用户进程被创建的时候,系统会自动为该进程创建三个数据 流,也就是题目中所提到的这三个.那么什么是数据流呢(stream)? 我们知道,一个程序要运行,需要有输入.输出,如果出错, ...

  4. LINUX获取文件信息

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  5. spring之构造注入

    第一种:通过构造name和value属性(不常用) <!-- userAction --> <bean id="userAction" class="c ...

  6. 同一台机器上多个tomcat启动造成的内存溢出问题的解决方法。

    加下面这句话就行了,我是WIN10+双tomcat+nginx(本地站点),无压力.在编译器的vm option里面加哦. -server -Xms512m -Xmx1024m -XX:PermSiz ...

  7. Angular4---部署---Angular 与 Nginx的邂逅

    Nginx + Angular结合操作 1.下载Nginx , 根据自己的版本下载Nginx,关于Nginx配置,请看https://www.cnblogs.com/MBirds/p/6605366. ...

  8. vue调试工具之 vue-devtools的安装

    这里介绍一下vue-devtools的安装方法之一: chrome浏览器的应用商店不能直接访问(需要跨域),所以直接应用商店安装的方法就行不通了. 1.到github主页去下载安装: git clon ...

  9. CSS中可以继承和不可继承的常见属性

    一.无继承性的属性 1.display:规定元素应该生成的框的类型 2.文本属性: vertical-align:垂直文本对齐 text-decoration:规定添加到文本的装饰 text-shad ...

  10. Apollo阿波罗配置中心docker

    前言 在分布式系统中,要改个配置涉及到很多个系统,一个一个改效率低下,吃力不讨好.用配置中心可以解决这个问题.当然配置中心有不少,以下对比的表格是照搬Apollo Wiki的. 功能点 Apollo ...