函数式

JavaScript是以函数为一等公民的函数式语言。函数在JavaScript中也是一个对象(继承制Function),函数也可以作为参数传递成函数变量。最近几年函数式也因为其无副作用的特性、透明性、惰性计算等在高并发,大数据领域火起来了。

JavaScript中也有如Underscore、lodash之类的函数式库,如lodash的使用方式:

var names = _.chain(users)
.map(function(user){
return user.user;
})
.join(" , ")
.value();
console.log(names);

关于lodash更多内容请参考JavaScript工具库之Lodash.

柯里化

今天文章将以高阶函数中的柯里化方式来,看看JavaScript的函数式能力。

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。

在理论计算机科学中,柯里化提供了在简单的理论模型中比如只接受一个单一参数的lambda 演算中研究带有多个参数的函数的方式。

JavaScript的柯里化实现

下边的例子,我们将把柯里化方式泛化为接受任意个参数,直到声明的方法参数个数饱和才执行,所以根据参数个数可以有多种柯里化函数产生。

代码如下:

(function(global) {
var FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m,
FN_ARG_SPLIT = /,/,
FN_ARG = /^\s*(_?)(\S+?)\1\s*$/,
STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var getArgLength = function(func) {
var fnText = func.toString().replace(STRIP_COMMENTS, '');
var argDecl = fnText.match(FN_ARGS);
var params = [];
argDecl[1].split(FN_ARG_SPLIT).forEach(function(arg) {
arg.replace(FN_ARG, function(all, underscore, name) {
params.push(name);
});
});
return params.length;
};
var curryFunc = function(func, len) {
len = len || getArgLength(func);
var args = [];
if (len === 0) {
return func.apply(null);
}
return function() {
[].push.apply(args, [].slice.apply(arguments));
if (args.length >= len) {
return func.apply(null, args);
}
return arguments.callee;
};
};
global.curryFunc = curryFunc;
})(this);
function add(x, y, z) {
return x + y + z;
}
console.log("result 1:", curryFunc(add)(1, 2)(3));
console.log("result 2:", curryFunc(add)(1)(2, 3));
console.log("result 3:", curryFunc(add)(1)(3)(2));
function add(x, y, z) {
return x * y * z;
}
console.log("result 1:", curryFunc(add)(2, 4)(6));
console.log("result 2:", curryFunc(add)(2)(4, 6));
console.log("result 3:", curryFunc(add)(2)(6)(4));
function sayHello() {
return "hello";
}
console.log(curryFunc(sayHello));

首先上面会利用正则来获取传入函数的参数个数。再返回一个函数的代理,每次的调用都会将传入参数缓存在args临时变量中,直到参数个数饱和才会立即执行。代码比较冗长,慢慢品味,当然有不足之处,也希望大家指出来。

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

  1. Javascript函数柯里化(curry)

    函数柯里化currying,是函数式编程非常重要的一个标志.它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去.我们依靠这个特性编写很多优雅酷炫的代 ...

  2. JavaScript函数柯里化的一些思考

    1. 高阶函数的坑 在学习柯里化之前,我们首先来看下面一段代码: var f1 = function(x){ return f(x); }; f1(x); 很多同学都能看出来,这些写是非常傻的,因为函 ...

  3. javascript函数柯里化初探

    // 柯里化之前 function add(x,y,z){ return x+y+z; } add(1,2,3) // 6 // 柯里化之后 function curryAdd(x){ return ...

  4. 深入理解javascript函数进阶系列第二篇——函数柯里化

    前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...

  5. 简单粗暴详细讲解javascript实现函数柯里化与反柯里化

    函数柯里化(黑人问号脸)???Currying(黑人问号脸)???妥妥的中式翻译既视感:下面来一起看看究竟什么是函数柯里化: 维基百科的解释是:把接收多个参数的函数变换成接收一个单一参数(最初函数的第 ...

  6. JavaScript中的事件循环机制跟函数柯里化

    一.事件循环机制的理解 test();//按秒输出5个5 function test() { for (var i = 0; i < 5; i++) { setTimeout(() => ...

  7. 一道javascript面试题(闭包与函数柯里化)

    要求写一个函数add(),分别实现能如下效果: (1)console.log(add(1)(2)(3)(4)()); (2)console.log(add(1,2)(3,4)()); (3)conso ...

  8. 精读JavaScript模式(六),Memoization模式与函数柯里化的应用

    假期就这么结束了!十天假就有三天在路上,真的难受!想想假期除了看了两场电影貌似也没做什么深刻印象的事情.流浪地球,特效还是很赞,不过对于感情的描写还是逃不掉拖沓和尴尬的通病,对于国产科幻还是抱有支持的 ...

  9. JavaScript之函数柯里化

    什么是柯里化(currying)? 维基百科中的解释是:柯里化是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术.意思就是当函 ...

随机推荐

  1. android 很多牛叉布局github地址(转)

    原文地址 http://blog.csdn.net/luo15309823081/article/details/41449929 点击可到达github-------https://github.c ...

  2. fname

    from lxml import etreeimport requestsdef getHtml(html): novelcontent = requests.get(html).content re ...

  3. [11]APUE:(文件)记录锁

    [a] 概念 建议锁:在遵循相同记录锁规则的进程间生效,通常用于保证某个程序自身多个进程间的数据一致性 强制锁:意在保证所有进程间的数据一致性,但不一定有效:如不能应对先 unlink 后建立同名副本 ...

  4. sqlserver开启'xp_cmdshell'命令

    --sql server中开启xp_cmdshell命令 1. --允许配置高级选项 GO RECONFIGURE GO . --开启xp_cmdshell服务 RECONFIGURE GO . -- ...

  5. 异常处理和JDBC

    1.异常: 格式:try{ 要执行的可能出现异常的语句 } catch(Exception e){ 对异常进行处理的语句 }    finally{    一定会被处理的语句 //可以不写 } 当需要 ...

  6. session和cookie的简单理解

    0. 引子,我们为什么要cookie和session       因为http请求是无状态的(不能记录用户的登录状态等),所以需要某种机制来保存用户的登录状态等信息,在下次访问web服务的时候,不用再 ...

  7. viewpage 循环滑动播放图片

    一般来说,viewpage 只支持图片的顺序滑动播放,在滑到边界时就再也滑不动了,如果要想继续滑动,只能向两边额外增加一张相片,即把第一张相片的位置放在最后一张图片的后面,给用户的感觉我继续滑就滑到了 ...

  8. 置入式模型inclusion model和显示具现化

    1.置入式模型 链接错误: 大多数非模板程序代码的组织如下:A,类声明在头文件中: B:全局变量和非inline函数在cpp文件中定义 但是,如果模板程序也这样组织,则会出错.原因在于:函数模板的定义 ...

  9. 使用sklearn优雅地进行数据挖掘

    目录 1 使用sklearn进行数据挖掘 1.1 数据挖掘的步骤 1.2 数据初貌 1.3 关键技术2 并行处理 2.1 整体并行处理 2.2 部分并行处理3 流水线处理4 自动化调参5 持久化6 回 ...

  10. [UCSD白板题] Huge Fibonacci Number modulo m

    Problem Introduction The Fibonacci numbers are defined as follows: \(F_0=0\), \(F_1=1\),and \(F_i=F_ ...