Introduction to JavaScript currying functions _javascript Tips

Source: Internet
Author: User
Tags javascript currying
The earliest curry function is a bit polymorphic in that it chooses the internal branch according to the function parameters:
Copy Code code as follows:

Http://www.openlaszlo.org/pipermail/laszlo-user/2005-March/000350.html
★★on 8 Mar, 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);

A pioneer in Japan may be able to make a function that is closer to the modern currying meaning with very complex regular and eval when it is not clear that arguments can also be converted to arrays using the native method of array.
Copy Code code as follows:

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;
}

<textarea id="runcode12313"><script type= "Text/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; function sum (x, y) {return x + y; function Mean3 (A, B, c) {return (A + B + C)/3; var a = Curry (sum) () alert (a)//25 var B = Curry (MEAN3) (10) (20, 30); Alert (b)//20 var c = Curry (Curry (sum)) (10) (20); alert (c); var d = Curry (Curry (MEAN3) (10)) (20) (30); alert (d); </script></textarea>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

Then is the closure of the popular, with the array of conversion arguments technology discovery, the modern currying function finally came into being, just like the 15~17 century of the great maritime era of the geographical discovery, JavaScript world suddenly open a lot.
Copy Code code as follows:

A simple modern currying function
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);
};
}

The general currying function is only two-fold, the execution is as follows, the first execution parameter is insufficient to return the internal function, the second execution is finished finally. However, for this parameter, we can still do some articles. Look at the following function:
Copy Code code as follows:

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

There is no such thing as a parametric problem, passing in a parameter, which is also computed. But do not pass the parameters? No mistake, the difference is that there are no parameters. We can let it continue to execute itself if the parameters exist in the case. Finally, in the absence of parameters, one-time execution. In other words, the previous steps are used to store the parameters.
Copy Code code as follows:

var sum2= curry (sum);
Sum2= sum2 (1) (2) (3) (4) (5);

Sum2 (); 15

This is a bit more difficult than the general currying function. Look at the annotation specifically:
Copy Code code as follows:

var curry= function (FN) {//parameters of the original function are functions
return function (args) {//Internal functions are an array of arguments, as immediate execution, so go straight to the third
Args is relative to the third, but the internal function is a global variable.
var self= arguments.callee;//saves itself (that is, the second function of the array as a parameter)
return function () {//This is the second call functions
if (arguments.length) {//If there are any parameters to add
[].push.apply (args,arguments);//apply put all current incoming parameters into args
return self (args);
}else{
Return fn.apply (This,args);//apply's second argument is an array
}
}
}([]);
};

Copy Code code as follows:

function sum () {
var result=0;
For (Var i=0, n=arguments.length i<n; i++) {
result = Arguments[i];
}
return result;
};
var curry = function (fn) {//parameters of the original function are functions
return function (args) {//Internal functions are an array of arguments, as immediate execution, so go straight to the third
var self= arguments.callee;//to save itself
return function () {//This is the second call functions
if (arguments.length) {//If there are any parameters to add
[].push.apply (Args,arguments);
return self (args);
}
else return fn.apply (This,args);//Execute
}
}([]);
};
var sum2= curry (sum);
Sum2= sum2 (1) (2) (3) (4) (5);
Alert (sum2 ());

or pass in multiple parameters at a time:
Copy Code code as follows:

function sum () {
var result=0;
For (Var i=0, n=arguments.length i<n; i++) {
result = Arguments[i];
}
return result;
};
var curry = function (fn) {//parameters of the original function are functions
return function (args) {//Internal functions are an array of arguments, as immediate execution, so go straight to the third
var self= arguments.callee;//to save itself
return function () {//This is the second call functions
if (arguments.length) {//If there are any parameters to add
[].push.apply (Args,arguments);
return self (args);
}
else return fn.apply (This,args);//Execute
}
}([]);
};
var sum2= curry (sum);
sum2= sum2 (1,2,3);
sum2= sum2 (4,5,6);
sum2= sum2 (7,8,9);
Alert (sum2 ());

But the above function has deficiencies, finally how to put parentheses, we think as long as the parameters are sufficient to return the result, the extra parameters are ignored. Improvements are as follows:
Copy Code code as follows:

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 ([]);
}

<script type= "Text/javascript" > Function curry (f) {if (F.len Gth = = 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 ([]); function Mean3 (A, B, c) {return (A + B + C)/3;} var curriedMean3 = Curry (MEAN3); Alert (CURRIEDMEAN3 (1) (2, 3)); => 2 Alert (CURRIEDMEAN3 (1) (2) (3))//NULL Bracket Invalid alert (CURRIEDMEAN3 () (1) () (2) (3)); => 2 Alert (CURRIEDMEAN3 (1, 2) (3, 4)); => 2 (Invalid fourth argument) </script>
[ctrl+a All selected note: If you need to introduce external JS need to refresh to perform]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.