Javascriptcurrying: function _ javascript

Source: Internet
Author: User
The currying function is a function that returns a function and is one of the greatest applications of a closure. For more detailed definitions of closures, see here and here. The following is a definition of the currying function. The earliest curry function is a little polymorphism, that is, the Branch is selected internally Based on the function parameters:

The Code is as follows:


// Http://www.openlaszlo.org/pipermail/laszlo-user/2005-March/000350.html
//★★On 8 Mar 2005, at, 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 use a very complex Regular Expression and eval to create a function closer to the meaning of modern currying when the native method of Array can be used to convert arguments to an Array.

The Code is 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;
}


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) (10) (15) alert () // 25 var B = curry (mean3) (10) (20, 30); alert (B) // 20 var c = curry (sum) (10) () (20); alert (c); var d = curry (mean3) (10) (20) (30); alert (d );
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]


Next comes the popularity of closures. With the discovery of array-converted arguments technology, the modern currying function has finally appeared, just like 15 ~ The geographic discoveries in the age of the 17th century have suddenly broadened the world of javascript.

The Code is 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 );
};
}


Generally, the currying function only has two duplicates. The execution is as follows. If the first execution parameter is insufficient, the internal function is returned, and the second execution is complete. However, we can make some articles about this parameter. See the following functions:

The Code is as follows:


Function sum (){
Var result = 0;
For (var I = 0, n = arguments. length; I Result + = arguments [I];
}
Return result;
}
Alert (sum (1, 2, 3, 4, 5); // 15


There is no such problem as parameter insufficiency. If a parameter is input, it is also calculated. But what about not passing in parameters? No error. The difference is that there are no parameters. We can keep it running, if the parameter exists. Finally, if there is no parameter, It will be executed once. In other words, the preceding steps are used to store parameters.
Var sum2 = curry (sum );
Sum2 = sum2 (1) (2) (3) (4) (5 );
Sum2 (); // 15
This is a little more difficult than the general currying function. For more information, see annotations:

The Code is as follows:


Var curry = function (fn) {// the parameter of the original function is a function
Return function (args) {// the parameter of the internal function is an array. Since it is executed immediately, it goes directly to the third deduplication.
// Args is a global variable relative to the third internal function.
Var self = arguments. callee; // save itself (that is, the second function with the array as the parameter)
Return function () {// This is the second function called
If (arguments. length) {// if there are other parameters to be added
[]. Push. apply (args, arguments); // apply put all the currently passed parameters into args
Return self (args );
} Else {
Return fn. apply (this, args); // The second parameter of apply is an array.
}
}
} ([]);
};


Function sum () {var result = 0; for (var I = 0, n = arguments. length; I <n; I ++) {result + = arguments [I];} return result ;}; var curry = function (fn) {// the parameter of the original function is the return function (args) {// the parameter of the internal function is an array. Because the function is executed immediately, the var self = arguments is removed directly to the third place. callee; // save itself. return function () {// This is the second function called if (arguments. length) {// if there are other parameters to be added []. 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 ());
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]


Or multiple parameters are input at a time:

Function sum () {var result = 0; for (var I = 0, n = arguments. length; I <n; I ++) {result + = arguments [I];} return result ;}; var curry = function (fn) {// the parameter of the original function is the return function (args) {// the parameter of the internal function is an array. Because the function is executed immediately, the var self = arguments is removed directly to the third place. callee; // save itself. return function () {// This is the second function called if (arguments. length) {// if there are other parameters to be added []. push. apply (args, arguments); return self (args);} else return fn. apply (this, args); // execute} ([]) ;}; var sum2 = curry (sum); sum2 = sum2 (, 3 ); sum2 = sum2 (4, 5, 6); sum2 = sum2 (7, 8, 9); alert (sum2 ());
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]


However, there are deficiencies in the above function, and we should put a bracket in the end. We want to return the result as long as the parameter is sufficient, and ignore the extra parameters. The improvements are as follows:

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


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 ([]);} 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 )); // The empty brackets are invalid. alert (curriedMean3 () (1) (2) (3); // => 2 alert (curriedMean3 (1, 2) (3, 4); // => 2 (the fourth parameter is invalid)
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]

Related Article

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.