Home  >  Article  >  Web Front-end  >  javascript currying functions that return functions_javascript tips

javascript currying functions that return functions_javascript tips

WBOY
WBOYOriginal
2016-05-16 18:42:001395browse

The earliest curry function was a bit polymorphic, that is, branches were selected internally based on function parameters:

Copy code The code is as follows:

//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);


A pioneer in Japan may have used very complex regularization and eval to come up with a function that is closer to the meaning of modern currying before he figured out that arguments can also be converted into arrays using Array's native method.

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


[Ctrl A Select all Note: If you need to introduce external Js, you need to refresh to execute ]

Then the popularity of closures , and with the discovery of the technology of array conversion arguments, the modern currying function finally made its debut. Just like the geographical discovery of the Age of Discovery in the 15th to 17th centuries, the world of JavaScript suddenly opened up a lot.
Copy code 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);
};
}

General currying functions only have two functions. The execution situation is as follows. The first execution has insufficient parameters and returns to the internal function, and the second execution is finally completed. However, we can still do some articles regarding this parameter. Look at the following function:
Copy code The code is as follows:

function sum(){
var result=0;
for(var i=0, n=arguments.length; iresult = arguments[i];
}
return result;
}
alert(sum(1,2,3,4,5)); // 15

There is no so-called insufficient parameter problem. If you pass in a parameter, it will also calculate it. But what if no parameters are passed in? Correct, the difference is whether there are parameters or not. We can make it execute itself continuously if the parameters are present. Finally, it is executed once without parameters. In other words, the previous steps are used to store parameters.
var sum2= curry(sum);
sum2= sum2(1)(2)(3)(4)(5);
sum2(); // 15
Compared to the general Currying functions, this is a bit difficult. See the comments for details:
Copy code The code is as follows:

var curry= function(fn){ //The parameters of the original function are functions
return function(args){//The parameters of the internal function are arrays. Since they are executed immediately, they go directly to the third level
//args is relative to the third level internal The function can be a global variable
var self= arguments.callee;//Save itself (that is, the second function with the array as a parameter)
return function(){ //This is the second call Function
if(arguments.length){//If there are more parameters to be added
[].push.apply(args,arguments);//apply puts all the parameters currently passed in into args
return self(args);
}else{
return fn.apply(this,args);//The second parameter of apply is the array
}
}
}([ ]);
};


Or pass in multiple parameters each time:

But the above function has shortcomings. We need to put parentheses in the end. We want to return the result as long as the parameters are sufficient, and the extra parameters are ignored. The improvement is as follows:
<.>Copy code 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([]);
}



[Ctrl A select all Note: If you need to introduce external Js, you need to refresh to execute ]
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn