时间:2016-02-17 22:49 来源: 我爱IT技术网 作者:佚名
欢迎您访问我爱IT技术网,今天小编为你分享的javascript教程:【javascript的currying函数介绍】,下面是详细的讲解!
javascript的currying函数介绍
最早期的curry函数有点多态的意味,就是根据函数参数在内部选用分支:
代码如下:
//http://www.openlaszlo.org/pipermail/laszlo-user/2005-March/000350.html
// ★★On 8 Mar 2005, at 00:06, Steve Albin wrote:
function add(a, b) {
if (arguments.length < 1) {
return add;
} else if (arguments.length < 2) {
return function(c) { return a + c }
} else {
return a + b;
}
}
var myadd=add( 2 );
var total=myadd(3);
日本的一个先行者可能在未搞清arguments也能用Array的原生方法转换为数组的时候,用非常复杂的正则与eval搞出一个更接近现代currying意味的函数。
//http://www.openlaszlo.org/pipermail/laszlo-user/2005-March/000350.html
// ★★On 8 Mar 2005, at 00:06, Steve Albin wrote:
function add(a, b) {
if (arguments.length < 1) {
return add;
} else if (arguments.length < 2) {
return function(c) { return a + c }
} else {
return a + b;
}
}
var myadd=add( 2 );
var total=myadd(3);
日本的一个先行者可能在未搞清arguments也能用Array的原生方法转换为数组的时候,用非常复杂的正则与eval搞出一个更接近现代currying意味的函数。
代码如下:
function curry(fun) {
if (typeof fun !='function') {
throw new Error("The argument must be a function.");
}
if (fun.arity==0) {
throw new Error("The function must have more than one argument.");
}
var funText=fun.toString();
var args=/function .*\((.*)\)(.*)/.exec(funText)[1].split(', ');
var firstArg=args.shift();
var restArgs=args.join(', ');
var body=funText.replace(/function .*\(.*\) /, "");
var curriedText=
"function (" + firstArg + ") {" +
"return function (" + restArgs + ")" + body +
"}";
eval("var curried=" + curriedText);
return curried;
}
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
接着是闭包的流行,与数组转换arguments的技术的发现,现代currying函数终于粉墨登场,就好像15~17世纪大航海时代的地理大发现,javascript的世界突然间开阔了许多。
function curry(fun) {
if (typeof fun !='function') {
throw new Error("The argument must be a function.");
}
if (fun.arity==0) {
throw new Error("The function must have more than one argument.");
}
var funText=fun.toString();
var args=/function .*\((.*)\)(.*)/.exec(funText)[1].split(', ');
var firstArg=args.shift();
var restArgs=args.join(', ');
var body=funText.replace(/function .*\(.*\) /, "");
var curriedText=
"function (" + firstArg + ") {" +
"return function (" + restArgs + ")" + body +
"}";
eval("var curried=" + curriedText);
return curried;
}
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
接着是闭包的流行,与数组转换arguments的技术的发现,现代currying函数终于粉墨登场,就好像15~17世纪大航海时代的地理大发现,javascript的世界突然间开阔了许多。
代码如下:
//一个简单的现代currying函数
function curry (fn, scope) {
var scope=scope || window;
var args=[];
for (var i=2, len=arguments.length; i < len; ++i) {
args.push(arguments[i]);
};
return function() {
fn.apply(scope, args);
};
}
一般的currying函数只有两重,执行情况如下,第一次执行参数不足返回内部函数,第二次执行才最终完成。不过针对这参数,我们还是可以做一些文章。看如下函数:
//一个简单的现代currying函数
function curry (fn, scope) {
var scope=scope || window;
var args=[];
for (var i=2, len=arguments.length; i < len; ++i) {
args.push(arguments[i]);
};
return function() {
fn.apply(scope, args);
};
}
一般的currying函数只有两重,执行情况如下,第一次执行参数不足返回内部函数,第二次执行才最终完成。不过针对这参数,我们还是可以做一些文章。看如下函数:
代码如下:
function sum(){
var result=0;
for(var i=0, n=arguments.length; i<n; i++){
result +=arguments[i];
}
return result;
}
alert(sum(1,2,3,4,5)); // 15
这就没有所谓的参数不足问题,传入一个参数,它也计算。但不传入参数呢?无错,区别在于有没有参数。我们可以让它不断执行自身,如果参数存在的情况下。最后在没有参数的情况下,一次过执行。换言之,前面的步骤是用于储存参数。
function sum(){
var result=0;
for(var i=0, n=arguments.length; i<n; i++){
result +=arguments[i];
}
return result;
}
alert(sum(1,2,3,4,5)); // 15
这就没有所谓的参数不足问题,传入一个参数,它也计算。但不传入参数呢?无错,区别在于有没有参数。我们可以让它不断执行自身,如果参数存在的情况下。最后在没有参数的情况下,一次过执行。换言之,前面的步骤是用于储存参数。
代码如下:
var sum2=curry(sum);
sum2=sum2(1)(2)(3)(4)(5);
sum2(); // 15
比起一般的currying函数,这有点难度。具体看注解:
var sum2=curry(sum);
sum2=sum2(1)(2)(3)(4)(5);
sum2(); // 15
比起一般的currying函数,这有点难度。具体看注解:
代码如下:
var curry=function(fn){//原函数的参数为函数
return function(args){//内部函数的参数为数组,由于立即执行,因此直接到第三重去
//args是相对于第三重内部函数可是全局变量
var self=arguments.callee;//把自身保存起来(就是那个数组为参数的第二重函数)
return function(){ //这才是第二次调用的函数
if(arguments.length){//如果还有要添加的参数
[].push.apply(args,arguments);//apply把当前传入的所有参数放进args中
return self(args);
}else{
return fn.apply(this,args);//apply的第二参数为数组
}
}
}([]);
};
var curry=function(fn){//原函数的参数为函数
return function(args){//内部函数的参数为数组,由于立即执行,因此直接到第三重去
//args是相对于第三重内部函数可是全局变量
var self=arguments.callee;//把自身保存起来(就是那个数组为参数的第二重函数)
return function(){ //这才是第二次调用的函数
if(arguments.length){//如果还有要添加的参数
[].push.apply(args,arguments);//apply把当前传入的所有参数放进args中
return self(args);
}else{
return fn.apply(this,args);//apply的第二参数为数组
}
}
}([]);
};
代码如下:
function sum(){
var result=0;
for(var i=0, n=arguments.length; i<n; i++){
result +=arguments[i];
}
return result;
};
var curry=function(fn){//原函数的参数为函数
return function(args){//内部函数的参数为数组,由于立即执行,因此直接到第三重去
var self=arguments.callee;//把自身保存起来
return function(){ //这才是第二次调用的函数
if(arguments.length){//如果还有要添加的参数
[].push.apply(args,arguments);
return self(args);
}
else return fn.apply(this,args);//执行
}
}([]);
};
var sum2=curry(sum);
sum2=sum2(1)(2)(3)(4)(5);
alert(sum2());
或者每次传入多个参数:
function sum(){
var result=0;
for(var i=0, n=arguments.length; i<n; i++){
result +=arguments[i];
}
return result;
};
var curry=function(fn){//原函数的参数为函数
return function(args){//内部函数的参数为数组,由于立即执行,因此直接到第三重去
var self=arguments.callee;//把自身保存起来
return function(){ //这才是第二次调用的函数
if(arguments.length){//如果还有要添加的参数
[].push.apply(args,arguments);
return self(args);
}
else return fn.apply(this,args);//执行
}
}([]);
};
var sum2=curry(sum);
sum2=sum2(1)(2)(3)(4)(5);
alert(sum2());
或者每次传入多个参数:
代码如下:
function sum(){
var result=0;
for(var i=0, n=arguments.length; i<n; i++){
result +=arguments[i];
}
return result;
};
var curry=function(fn){//原函数的参数为函数
return function(args){//内部函数的参数为数组,由于立即执行,因此直接到第三重去
var self=arguments.callee;//把自身保存起来
return function(){ //这才是第二次调用的函数
if(arguments.length){//如果还有要添加的参数
[].push.apply(args,arguments);
return self(args);
}
else return fn.apply(this,args);//执行
}
}([]);
};
var sum2=curry(sum);
sum2=sum2(1,2,3);
sum2=sum2(4,5,6);
sum2=sum2(7,8,9);
alert(sum2());
但上面的函数有不足之处,最后怎么也要放个括号,我们想只要参数足够就返回结果,多出的参数忽略。改进如下:
function sum(){
var result=0;
for(var i=0, n=arguments.length; i<n; i++){
result +=arguments[i];
}
return result;
};
var curry=function(fn){//原函数的参数为函数
return function(args){//内部函数的参数为数组,由于立即执行,因此直接到第三重去
var self=arguments.callee;//把自身保存起来
return function(){ //这才是第二次调用的函数
if(arguments.length){//如果还有要添加的参数
[].push.apply(args,arguments);
return self(args);
}
else return fn.apply(this,args);//执行
}
}([]);
};
var sum2=curry(sum);
sum2=sum2(1,2,3);
sum2=sum2(4,5,6);
sum2=sum2(7,8,9);
alert(sum2());
但上面的函数有不足之处,最后怎么也要放个括号,我们想只要参数足够就返回结果,多出的参数忽略。改进如下:
代码如下:
function curry(f) {
if (f.length==0) return f;
function iterate(args) {
if (args.length <=f.length)
return f.apply(null, args);
return function () {
return iterate(args.concat(Array.prototype.slice.call(arguments)));
};
}
return iterate([]);
}
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
function curry(f) {
if (f.length==0) return f;
function iterate(args) {
if (args.length <=f.length)
return f.apply(null, args);
return function () {
return iterate(args.concat(Array.prototype.slice.call(arguments)));
};
}
return iterate([]);
}
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
关于javascript的currying函数介绍的用户互动如下:
相关问题:JS 中 var add=function add;是什么简写
答:Currying 实际上是一个很漂亮的技术,你可以给一个参数固定一个参数后再把返回值(也就是接受剩余参数的函数)作为参数传递给其它函数。在 JavaScript 这种重度依赖对... >>详细
相关问题:招聘JavaScript 程序员时应该问什么问题
答:最喜欢哪个? 为什么?自己有写过类库吗? 比如 DOM 的扩展。有使用过服务端 JavaScript 框架吗?ECMAScript 和 JavaScript 的区别是什么?有用过 JavaScript 代码校验工具吗?有读过或推荐的 JavaScirpt 书籍吗?会为你的 JavaScript 代码写单元测试吗... >>详细
相关问题:招聘JavaScript 程序员时应该问什么问题
答:==通用:使用过类库吗? 最喜欢哪个? 为什么?自己有写过类库吗? 比如 DOM 的扩展。有使用过服务端 JavaScript 框架吗?ECMAScript 和 JavaScript 的区别是什么?有用过 JavaScript 代码校验工具吗?有读过或推荐的 JavaScirpt 书籍吗?会为你的 JavaS... >>详细
- 【firefox】firefox浏览器不支持innerText的解决
- 【Extjs】Extjs学习过程中新手容易碰到的低级错误
- 【clearInterval】js clearInterval()方法的定义
- 【ComboBox】ComboBox 和 DateField 在IE下消失的
- 【ajax】用js来解决ajax读取页面乱码-页面乱码
- 【addEventListener】addEventListener和attachEv
- 【dom】javascript dom追加内容实现示例-追加内容
- 【has】基于jquery的has()方法以及与find()方法以
- 【browser】jQuery下通过$.browser来判断浏览器.-
- 【extjs】Extjs入门之动态加载树代码-动态加载树
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
