Author: CAI Xuguang
An interview question
We have an Add method.
function add(a, b, c) {
return a + b + c;
}
add(1.2.3) / / 6
Copy the code
Implement a sum method that satisfies the following conditions:
sum(1) (2.3) / / 6
sum(1) (2) (3) / / 6
Copy the code
In fact, this problem uses the idea of function Currization, and we can convert the add method into the sum method by means of function Currization.
So let’s see what a function corrification is.
What is the Currization of a function
Wikipedia defines currification as follows:
In computer science, Currying, also translated as carryization or callization, is a technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function), and returning a new function that takes the remaining arguments and returns a result.
In plain English: Call a function with just a few arguments and let it return a new function to handle the rest.
Here’s an example of understanding Currization:
Let’s say you have a store, and it’s on sale, and you want to give regular customers a 10% discount on everything.
function setDiscount(price, discount) {
return price * discount;
}
Copy the code
When an ordinary customer buys a commodity that costs 100 yuan, you can calculate the price:
const price = setDiscount(100.0.9);
Copy the code
You will find that every time you calculate the price of an item, you need to enter the price and discount, which is very troublesome.
const price1 = setDiscount(500.0.9);
const price2 = setDiscount(1000.0.9);
const price3 = setDiscount(2000.0.9);
Copy the code
We can corrize the function setDiscount to avoid entering discount every time.
function currySetDiscount(discount) {
return function(price) {
return discount * price;
};
}
const setNinetyPercent = currySetDiscount(0.9);
Copy the code
Now we can calculate the price of goods for the average customer:
const price = setNinetyPercent(500);
Copy the code
Similarly, for VIP customers, there is a 20% discount for all products, which can be calculated as follows:
const setEightyPercent = currySetDiscount(0.8);
const price = setEightyPercent(500);
Copy the code
This function can be understood as parameter reuse, delay execution, reduce code redundancy, increase code readability.
Simple implementation of currization of functions
Going back to the original problem, let’s write a Curry function.
function curry(fn, args) {
let len = fn.length; // The parameter length of the function to be currified
let tempArgs = args || [];
return function() {
tempArgs = tempArgs.concat([...arguments])
if (tempArgs.length < len) {
return curry.call(this, fn, tempArgs);
} else {
return fn.apply(this, tempArgs); }}; }Copy the code
The function is executed when the number of arguments is the same as that of the original function.
Add can be currified like this to generate the sum method:
var sum = curry(add);
sum(1) (2.3) / / 6
sum(1) (2) (3) / / 6
Copy the code
Application of currization of functions
Delay calculation
The bind function we use all the time.
let obj = {
name: 'jack'
}
let showName = function() {
console.log(this.name)
}
let showJackName = showName.bind(obj);
showJackName(); // jack
Copy the code
Here bind is used to change the context in which the function is executed, but the function itself is not executed, so it essentially delays the calculation.
If we look at the mock implementation of BIND, it’s essentially a currization.
function myBind(){
var self = this;
// The first object argument
var context = Array.prototype.shift.call(arguments);
// Other parameters
var bindArgs = Array.prototype.slice.call(arguments);
// temporary functions
var fTemp = function(){};
function fn(){
// Merge binding parameters and call-time parameters
var args = bindArgs.concat(Array.prototype.slice.call(arguments));
// Execute the original function (this refers to the given object)
self.apply(context, args);
}
// temporary function prototype refers to the original function prototype
fTemp.prototype = self.prototype;
// New function prototype set to temporary function instance object (when the original function uses New to create instance object)
fn.prototype = new fTemp();
return fn;
}
Copy the code
conclusion
Function currification is one of the most basic operations in functional programming (a programming paradigm). It is derived from and mainly serves functional programming (the combination of functions requires a single parameter function). We don’t really need to differentiate between functions in our daily development. Closures, higher-order functions, and so on are all similar to functions to some extent.