Using the term “Currying”
Conversions between pseudo-arrays and arrays merge arrays.
Currying is what?
In computer science, Currying is a technique that converts a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function), and returns a new function that takes the remaining arguments and returns a result. The technique was named after logician Haskell Curry by Christopher Strachey, although it was invented by Moses Schnfinkel and Gottlob Frege.
The significance of Currying is that it can completely transform a function into a fixed form that takes one argument and returns a value. After the function curry, it can only take one argument, and other arguments can be created as the “environment” for that function. This allows the function to return to its original one-parameter, one-value state, which reduces code redundancy and increases readability, making it easier to discuss and optimize.
How does Currying(Or Creaming) work?
It works by nesting functions for each possible argument, using natural closures created by the nested functions to preserve access to each successive argument.
vernacular
Read daily concept do not understand what meaning?
In Chinese, XX refers to the change of a thing, such as beautification, ugliness, emotion and complication.
Cremation is simply a wrapper around a function (method).
How will it be packaged?
Wrap a function with multiple arguments in such a way that it can accept one argument. Here’s an example:
function addition(a, b) {
return a + b;
}
addition(1.2); / / 3
// let it be supported
addition(1) (2); / / 3
Copy the code
To observe theaddition(1)(2)
Why can this function be called continuously? instructionsaddition(1)
Is still a function.
So there’s an implementation like this, so without further ado, let’s go to the code.
function currying(fn, ... args) {
// If the number of arguments is less than the original fn.length, the recursive call continues to collect arguments
// fn.length refers to the number of arguments to declare the function
if (args.length < fn.length) {
return (. newArgs) = >currying(fn, ... args, ... newArgs); }else {
return fn(...args);
}
}
function addition(a, b, c) {
return a + b + c;
}
let sum = currying(addition);
sum(3);Args. Length < fn.length, the return value is still a function
sum(1.2) (3.4);Sum (1,2) returns a function. Sum (1,2) returns a function. Then we call 3 and 4 again, passing in four arguments. So args.length > fn.length, so return fn(... Args, which is 1,2,3,4.
Copy the code
The advanced
I was quick to get tired of this, as I realized that it would not work forever, because when more arguments were passed than the original function declared, it would no longer return a function, so it would not continue to be called. Let’s look at the function I wrote:
function addition() {
if (!arguments.length) return;
return [...arguments].reduce((a, b) = > a + b);
}
Copy the code
This function even declares an argument of 0. I want to write a currying function that can be called (addition)(1)(2)(3)(4,5)(6,7,8)(9).
Here’s an interview question:
// Implement an add method that satisfies the following expectations:
// add(1)(2)(3) = 6;
// add(1, 2, 3)(4) = 10;
// add(1)(2)(3)(4)(5) = 15;
Copy the code
Straight up
function add(. args) {
// On the first execution, an array is defined to store all the parameters
let _args = args || [];
// Internally declare a function that uses closure properties to hold _args and collect all parameter values
let _adder = function (. newArgs) {
_args = _args.concat(newArgs); //_args = [..._args,...newArgs]
return _adder;
};
// Take advantage of the toString implicit conversion feature to implicitly convert when finally executed and calculate the final value returned
_adder.toString = function () {
return _args.reduce((a, b) = > a + b);
};
return _adder;
}
// console.log(add(1)(2, 4)); // f 7
// console.log(add(1)(2)(3)); // f 6
// console.log(add(1, 2, 3)(4)); // f 10
// console.log(add(1)(2)(3)(4)(5)); // f 15
// console.log(add(2, 6)(1)); // f 9
// console.log(typeof add(1)(2)); // function
// console.log(add(1)(2).toString()); // 3 <number>
// console.log(String(add(1)(2))); // 3 <string>
// console.log(Number(add(1)(2))); // 3 <number>
// console.log(add(1)(2) - 0); // 3 <number>
Copy the code
This gave rise to a common name for currying
function currying(fn, ... args1) {
// If fn is not passed, return
if(! fn)return;
const that = this;
// Define an array to store each passed argument
let args = args1 || [];
// Define a function foo, and finally return this function foo, so that functions can continue to be called after currying.
let foo = function (. args2) {
// Use an argument passed by a function that can continue to return a function or return a result (value).
if (args2.length === 0) {
// If a function after currying has no arguments, such as currying(addition)() or currying(1)(), return a result
returnfn.call(that, ... args); }else {
// Otherwise continue to return this function to continue collecting parameters
args = [...args, ...args2];
returnfoo; }};// Finally returns the defined function foo
return foo;
}
function addition() {
if (!arguments.length) return;
return [...arguments].reduce((a, b) = > a + b);
}
function subtraction(a, b) {
return a - b;
}
function multiplication(a, b) {
return a * b;
}
function division(a, b) {
return a / b;
}
console.log(currying(addition)(1) ());/ / 1
console.log(currying(addition)(2) (3) ());/ / 5
console.log(currying(multiplication, 5) (4) ());/ / 20
Copy the code
The effect of cremation
- Parameters of reuse
- Return earlier to improve applicability
- Delayed execution – The body of the function itself is not executed, which can be considered delayed execution
The function.prototype. bind method is also a Currified application.