JavaScript summary 5.0—Master Function Currying and its essence
JS series 5.0 is mainly a detailed explanation of function currying.
define
Definition of currying: Converting a function with multiple parameters into a single-parameter function chain, this transformation is called "currying" process, such as converting f(a,b,c) into f(a )(b)(c) to call
Function:
- Make the responsibility of the function more simple, process each incoming parameter in a single function and use the processed result in the next function; instead of passing all the parameters at once
for example:
function add(x,y,z){
return x+y+z
}
console.log(add(1,2,3)); //6
//currying
function add2(x){
x +=1
return function(y){
y *=2
return function(z){
z++
return x +y +z
}
}
}
console.log(add2(1)(2)(3)); //10
- Parameter multiplexing, such as passing in a function parameter that must be used in subsequent calls, and then using the returned function does not need to continue passing in this parameter
for example:
function foo(num){
return function(count){
return num-count
}
}
let subtraction = foo(100)
//Print the value of 100 minus a certain number
console.log( subtraction(10));//90
console.log( subtraction(50));//50
- Implement currying when printing logs
for example:
function log(date, importance, message) {
alert(`[${date.getHours()}:${date.getMinutes()}] [${importance}] ${message}`);
}
// Currying
log = _.curry(log);
// logNow will be a partial function of logs with a fixed first argument (i.e. find a specific range of logs)
let logNow = log(new Date());
// use
logNow("INFO", "message"); // [HH:mm] INFO message
Curry implementation
Implement add(1)(2)(3)() = 6; add(1)(2)(3)(4)() = 10 // function currying
function add(){
// Because the parameter is uncertain, it is not necessary to set the formal parameter
let args = [...arguments] //Convert the argunment class array into an array for subsequent implementation of the push method
// let args = Array.prototype.slice.call(arguments) can also be converted in this way
let inner = function(){
args.push(...arguments) //Accept the parameters passed in later and add them to the array of previously passed values
return inner
/*return The function itself, no matter how many parentheses (that is, how many times to call the function by passing parameters) returns the inner function,
In this way, any delayed input parameters can be called normally; and the function is implicitly converted to a string because the internal toString method is called */
}
// Modify the toString method so that the result is displayed normally instead of being printed as a function
inner. toString = function () {
//Achieve the title requirement: parameter addition
return args. reduce((pre,cur) => pre+cur)
}
//add function return value
return inner
}
let res = add(1)(3)(1,2)()
console.log(res); //The output is still the inner function, the browser will not execute the toString method automatically, it will only be executed once when alert
alert( add(1)(2)(3)()) //6
let res1 = add(1)(3)(2)(4).toString() //This method can also output 10, manually call the tostring method
console.log(res1);
Implement the currying function (pass in the function you define to curry it)
function myCurrying(fn) {
function curried(...args) {
//Judge the number of parameters currently received to determine whether it is consistent with the parameters that need to be accepted
// Execute the function when the parameter passed in is greater than or equal to the required parameter (the parameter of the fn function)
if (args. length >= fn. length) {
// return fn(...args)
// return fn. call(this, ...args)
return fn. apply(this, args)
} else {
// If the parameters have not been received yet, a new function needs to be returned to continue receiving new parameters
function curried2(...args2) {
// After receiving the parameters, you need to call curried recursively to check whether the number of functions reaches the number of parameters
return curried. apply(this, args. concat(args2))
}
return curried2
}
}
return curried
}
function add(x, y, z) {
return x + y + z
}
function mult(x,y,z){
return x*y*z
}
//implement add(1)(2)(3)(), and pass in the function add that needs to be curried
var curryAdd = myCurrying(add)(1)(2)(3) //6
console. log(curryAdd)
console.log(myCurrying(mult)(10)(1,2));//20