//反科里化
Function.prototype.uncurrying = function() {
var _this = this;
return function() {
return Function.prototype.call.apply(_this, arguments);
//_this.call(arguments);
//在下面的例子中Array.prototype.push == _this
//因为call 本身也是个函数
//Function.prototype.call.apply 就是去调用call()方法
//也就是Array.prototype.push.call(arguments);
//arguments 也就是 return function()中传入的参数组
//例子中push(arr,"a") arguments 就是[arr,"a"];
//apply第二个参数接受数组,arguments 是伪数组(Object 类型).
//call 接受参数序列 arg1, arg2, , argN ,arguments 会被转化成 arr , "a"
//所以实际上到最后我们得到的是
//Array.prototype.push.call(arr , "a");
//即 arr.push("a")
};
};

var arr = new Array();
Array.prototype.push.call(arr, "a"); //arr == ["a"]

var push = Array.prototype.push.uncurrying();
var arr = new Array();
push(arr, "a"); //arr == ["a"]
push(arr, "b"); //arr == ["a","b"]

var toUpperCase = String.prototype.toUpperCase.uncurrying();
var arr1 = arr.map(function(elem) {
return toUpperCase(elem); //map()迭代数组元素 A ,B,并把结果放在一个新数组中返回
})

console.log(arr1); //["A", "B"]

var arr2 = arr.forEach(function(elem, index) {
return toUpperCase(index + "." + elem);//foreach()只迭代数组元素,没有返回值 1.a 2.b
})

console.log(arr2); //undefined

var selfindexof = function() {

var ary = Array.prototype.shift.call(arguments);
return Array.prototype.indexOf.apply(ary, arguments);
//等价于 return Function.prototype.call.apply(Array.prototype.indexOf,arguments);

}

console.log(selfindexof(arr, "b"));// 1

var add_fn = function(obj, fn_keys) {
for (var i = 0, fn; fn = fn_keys[i++];) {~
~function(fn) {
var new_fn = Array.prototype[fn].uncurrying();
obj[fn] = function() {
new_fn.apply(this, [this].concat(Array.prototype.slice.call(arguments)));
//arguments是Object,Array.prototype.slice.call(arguments)将arguments转化成数组
//如果不转化concat之后得到的是[this,Object]
//转化之后concat之后得到的是[this,arguments[0],arguments[1]...]

return this;
};
}(fn)
}
}

var A = function() {

}

add_fn(A.prototype, ['push', 'indexOf', 'shift', 'pop', 'forEach']);

var a = new A;

console.log(a.push)
a.push(4).push(5).push(6).forEach(function(n, i) {
// alert(n);
})

/*科里化*/
Function.prototype.currying = function(){
//形成了闭包,所以_args会常驻内存中,因为闭包依赖于外部函数的变量
var _args = [];
var _this = this;
return function(){
if (arguments.length === 0) {
return _this.apply(this,_args);
}
[].push.apply(_args, arguments);
return arguments.callee;
}
}

//实现惰性计算
var monthly_cost = 0;

var monthly_cost_fn = function() {
for (var i = 0, c; c = arguments[i++];) {
monthly_cost += c;
}
return monthly_cost;
}.currying();

/*此时的monthly_cost_fn = function(){
if (arguments.length === 0) {
return _this.apply(this,_args);
}
[].push.apply(_args, arguments);
return arguments.callee;
}*/

monthly_cost_fn(100);
monthly_cost_fn(200);//有参数不会去计算,而是把参数存贮起来
monthly_cost_fn(300);

console.log(monthly_cost_fn.call());//参数为0,会去执行计算,得出600

Currying and Uncurrying Js的更多相关文章

  1. js高阶函数应用—函数柯里化和反柯里化(二)

    第上一篇文章中我们介绍了函数柯里化,顺带提到了偏函数,接下来我们继续话题,进入今天的主题-函数的反柯里化. 在上一篇文章中柯里化函数你可能需要去敲许多代码,理解很多代码逻辑,不过这一节我们讨论的反科里 ...

  2. JavaScript进阶之路——认识和使用Promise,重构你的Js代码

    一转眼,这2015年上半年就过去了,差不多一个月没有写博客了,"罪过罪过"啊~~.进入了七月份,也就意味着我们上半年苦逼的单身生活结束了,从此刻起,我们要打起十二分的精神,开始下半 ...

  3. (转)Array.prototype.slice.call自解

    很多框架或者库里面都会有这句的使用,最多的还是通过Array.prototype.slice.call(arguments,0)把arguments这个伪数组转换为真正的数组.但为什么可以这么做,却一 ...

  4. 彻底理解Javascript 中的 Promise(-------------------------------***---------------------------------)

    ES6原生提供了 Promise 对象. 到底是何方妖怪呢?打出来看看: 所谓 Promise,就是一个对象,用来传递异步操作的消息.它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个 ...

  5. JS中的反柯里化( uncurrying)

    反柯里化 相反,反柯里化的作用在与扩大函数的适用性,使本来作为特定对象所拥有的功能的函数可以被任意对象所用.即把如下给定的函数签名, obj.func(arg1, arg2) 转化成一个函数形式,签名 ...

  6. JS中的柯里化(currying)

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

  7. js 柯里化Currying

    今天读一篇博客的时候,看都有关柯里化的东西,由于好奇,特意查了一下,找到一篇比较好的文章,特意收藏. 引子先来看一道小问题:有人在群里出了到一道题目:var s = sum(1)(2)(3) .... ...

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

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

  9. Js中Currying的应用

    Js中Currying的应用 柯里化Currying是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术,是函数式编程应用. 描述 如果说函数式编程中有两 ...

随机推荐

  1. Jquery 页面初始化常用的三种方法以及Jquery 发送ajax 请求

    第一种 $(document).ready(function(){ //文档就绪事件 }); 第二种是第一种的简略写法,效果上和第一种是等效的. $(function(){ //文档加载事件,整个文档 ...

  2. laravel-ide-helper 遇到There are no commands defined问题怎么解决

    laravel门面类的代码提示方案: https://github.com/barryvdh/laravel-ide-helper 按照步骤安装 1.composer require barryvdh ...

  3. servlet对应.net中的http上下文

    java中的servlet在.net中其实就是http上下文.

  4. OD 实验(十三) - 对一个程序的逆向

    程序: 运行程序 点击 Start,它就会进行对系统的扫描 点击 About -> Enter Registration Code 随便输入一下内容,点击 OK,会弹出该弹窗 用 PEiD 看一 ...

  5. linux 监控系统剩余内存大小

    cur_free = `free -m | awk '/buffers\// {print $NF}'` chars="current memory is $cur_free." ...

  6. 14_java之变量|参数|返回值|修饰符

    01java中的文档注释和制作 * A: 在eclipse使用时,可以配合文档注释,导出对类的说明文档,从而供其 他人阅读学习与使用. 通过使用文档注释,将类或者方法进行注释用@简单标注基本信息.如@ ...

  7. Rhel5.5配置Centos yum源

    ruiy哥,抛砖引玉 当你使用rhel系统时,[大部分数据库中心及政府企业选择linux服务器时通常考虑采购的版本一般不外乎是Rhel红帽及Suse,理由你懂的EcoSystem!]你没有一个红帽网络 ...

  8. 说说JDK中的String.valueOf()传null的诡异处理

    都说JDK的实现诡异多,今儿也算是被我踩到一个坑了. 就来说说关于String.valueOf的这个坑. public class TestString { public static void ma ...

  9. 关于LOH(Large Object Heap)及内存泄漏

    关于LOH(Large Object Heap)的. .NET CLR中对于大于85000字节的内存既不像引用类型那样分配到普通堆上,也不像值类型那样分配到栈上,而是分配到了一个特殊的称为LOH的内部 ...

  10. tree的所有节点都勾选上或者取消勾选

    还有一个功能,就是让tree的所有节点都勾选上或者取消勾选,在api中找了一下有一个方法: check target 选中指定节点. 那我们只能是选中根节点后,实现全选. getRoot none 获 ...