Currying and Uncurrying Js
//反科里化
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的更多相关文章
- js高阶函数应用—函数柯里化和反柯里化(二)
第上一篇文章中我们介绍了函数柯里化,顺带提到了偏函数,接下来我们继续话题,进入今天的主题-函数的反柯里化. 在上一篇文章中柯里化函数你可能需要去敲许多代码,理解很多代码逻辑,不过这一节我们讨论的反科里 ...
- JavaScript进阶之路——认识和使用Promise,重构你的Js代码
一转眼,这2015年上半年就过去了,差不多一个月没有写博客了,"罪过罪过"啊~~.进入了七月份,也就意味着我们上半年苦逼的单身生活结束了,从此刻起,我们要打起十二分的精神,开始下半 ...
- (转)Array.prototype.slice.call自解
很多框架或者库里面都会有这句的使用,最多的还是通过Array.prototype.slice.call(arguments,0)把arguments这个伪数组转换为真正的数组.但为什么可以这么做,却一 ...
- 彻底理解Javascript 中的 Promise(-------------------------------***---------------------------------)
ES6原生提供了 Promise 对象. 到底是何方妖怪呢?打出来看看: 所谓 Promise,就是一个对象,用来传递异步操作的消息.它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个 ...
- JS中的反柯里化( uncurrying)
反柯里化 相反,反柯里化的作用在与扩大函数的适用性,使本来作为特定对象所拥有的功能的函数可以被任意对象所用.即把如下给定的函数签名, obj.func(arg1, arg2) 转化成一个函数形式,签名 ...
- JS中的柯里化(currying)
何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参 ...
- js 柯里化Currying
今天读一篇博客的时候,看都有关柯里化的东西,由于好奇,特意查了一下,找到一篇比较好的文章,特意收藏. 引子先来看一道小问题:有人在群里出了到一道题目:var s = sum(1)(2)(3) .... ...
- JS中的柯里化(currying) 转载自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
JS中的柯里化(currying) by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpr ...
- Js中Currying的应用
Js中Currying的应用 柯里化Currying是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数且返回结果的新函数的技术,是函数式编程应用. 描述 如果说函数式编程中有两 ...
随机推荐
- 用户的 添加 权限 MySql远程登录
添加一个用户 '; 为这个叫mongo的用户赋予操作z_0811数据库的所有权限 '; mysql如何修改开启允许远程连接 关于mysql远程连接的问题,大家在公司工作中,经常会遇到mysql数据 ...
- 关于@Autowired使用注意点
@Autowired是按类型进行装配的,那么我一个接口UserInterface,有多个实现类AImpl(@service(name="userInterface1")),BImp ...
- 二、jenkins配置email(以腾讯企业qq为例)
废话不多说,直接上干货: 主要针对两个部分进行介绍: 1.jenkins内置的邮件功能: 2.Editable Email Notification插件的邮件功能: 低版本的jenkins有很多插件都 ...
- 版本控制git之一 - 仓库管理
git 再开始这个话题之前,让我想起了一件很痛苦的事情,在我大学写毕业论文的时候,我当时的文件是这样保存的 毕业论文_初稿.doc 毕业论文_修改1.doc 毕业论文_修改2.doc 毕业论文_修改3 ...
- jstack来分析linux服务器上Java应用服务性能异常
使用jdk自带的jstack来分析linux服务器上应用服务性能异常: 1.top查找出哪个进程消耗的系统资源情况 [op1@jira ~]$ top top - 19:23:43 up 22 day ...
- Linux下编译、安装并启动apache
安装步骤如下: 1. 首先去http://httpd.apache.org/download.cgi上下载需要的apache源码,然后存放至/usr/local/src下[此源码存放路径可任意指定] ...
- 「小程序JAVA实战」小程序导航组件(26)
转自:https://idig8.com/2018/08/19/xiaochengxujavashizhanxiaochengxudaohangzujian26/ 来说下 ,小程序的导航组件.源码:h ...
- 一个简单的环境光shader
关于shader的一个简短的历史 在DirectX8之前,GPU有一个固定的方法去变换顶点和像素,称为“固定管线”.这使得在将它们传递给GPU后,开发者不可能操作顶点和像素的变换. DirectX8介 ...
- java 修改文件
public void fileAlter(String fileName,String content) throws IOException{ BufferedRe ...
- 读书笔记 Week6 2018-4-12
Chap 24 重构 读书笔记 一.需求的变更 单纯就科目学习中的小项目来说,目标在一开始便被明确下来,即可定义一份严谨的列表来描述功能.故在原来的编程经历中,只要上交了程序便一切都没事儿了,也没有重 ...