This is the fifth day of my participation in the August More text Challenge. For details, see: August More Text Challenge
1. To convert a function that takes multiple arguments to a function that takes a single argument (a single argument being the first of many arguments) and returns a new function that takes the remaining arguments and returns the result, i.e., f(a, b, c) to the callable f(a)(b)(c).
Function curlization idea: a JS preprocessing idea, reduce generality, improve applicability.
Features:
Parameters of reuse
: You need to enter multiple arguments. Finally, you only need to enter one. The rest is obtained using argumentsReturn early
: Avoid repeatedly judging whether a condition is met. If it is not met, return will not continue to perform the following operationsDelay the
Avoid repeating the process until you really need the results
// The normal add function
function add(x, y) {
return x + y
}
/ / after Currying
function curryingAdd(x) {
return function (y) {
return x + y
}
}
add(1.2) / / 3
curryingAdd(1) (2) / / 3
Copy the code
Advanced currying implementation
function curry (fn, currArgs) {
return function() {
let args = [].slice.call(arguments);
// If the last parameter currArgs is not provided on the first call, no args concatenation is required
if(currArgs ! = =undefined) {
args = args.concat(currArgs);
}
// Call recursively
if (args.length < fn.length) {
return curry(fn, args);
}
// Exit recursively
return fn.apply(null, args); }} orfunction currying(fn, ... args) {
if (args.length >= fn.length) {
returnfn(... args); }else {
return (. args2) = >currying(fn, ... args, ... args2); }}function sum(a, b, c) {
return a + b + c;
}
let curriedSum = curry(sum);
alert( curriedSum(1.2.3));// 6, can still be called normally
alert( curriedSum(1) (2.3));// 6, the first parameter of the curryization
alert( curriedSum(1) (2) (3));// 6, full currying
Copy the code
Currie use scenarios
1. Parameter reuse
Reduce the repeated passing of invariable parts of the parameter
function uri (protocol,hostname,pathname){
return `${protocol}${hostname}${pathname}`;
}
const uri1 = uri("https://"."www.site.com"."/page1");
const uri2 = uri("https://"."www.site.com"."/page2");
console.log(uri1);
console.log(uri2);
// Convert to a Curryized function
function uri_curring (protocol){
return function(hostname,pathname){
return `${protocol}${hostname}${pathname}`; }}const uri_https = uri_curring("https://");
console.log(uri_https);
const uri1 = uri_https("www.csdn.net"."/page1");
const uri2 = uri_https("www.baidu.com"."/page2");
console.log(uri1); // "https://www.csdn.net/page1"
console.log(uri2); // "https://www.baidu.com/page2"
Copy the code
2. Confirm in advance
Event listening: Performance will suffer because of the unnecessary performance overhead of running the if() statement every time on earlier versions of Internet Explorer.
var on = function(element, event, handler) {
if (document.addEventListener) {
if (element && event && handler) {
element.addEventListener(event, handler, false); }}else {
if (element && event && handler) {
element.attachEvent('on'+ event, handler); }}}// Run the whole function once
var on = (function() {
if (document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false); }}; }else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on'+ event, handler); }}; }}) ();// The isSupport parameter is set to isSupport. // The isSupport parameter is set to isSupport
var on = function(isSupport, element, event, handler) {
isSupport = isSupport || document.addEventListener;
if (isSupport) {
return element.addEventListener(event, handler, false);
} else {
return element.attachEvent('on'+ event, handler); }}Copy the code
3. Delay operation
Latency is also an important use case for Currying, as can bind and arrow functions.
function hello(name) {
console.log('Hello, ' + name);
}
setTimeout(hello('dreamapple'), 3600); // Execute immediately, not after 3.6s
setTimeout(function() {
hello('dreamapple');
}, 3600); // After 3.6 seconds
setTimeout(() = > {
hello('dreamapple');
}, 3600); // After 3.6 seconds
// Bind delays execution: the bind method is required to force binding to the context, i.e. the first argument to bind is referred to as this when the original function is run
setTimeout(hello.bind(this.'dreamapple'), 3600); // Execute the function after 3.6s
// Curlize delay execution
function curryingHelper(fn) {
var _args = Array.prototype.slice.call(arguments.1);
return function() {
var _newArgs = Array.prototype.slice.call(arguments);
var _totalArgs = _args.concat(_newArgs);
return fn.apply(this, _totalArgs); }}setTimeout(curryingHelper(hello, 'dreamapple'), 3600); // Execute the function after 3.6s
Copy the code
Classic topic
To determine the parameters
Function currying implementation of
function sum(a,b,c,d){
return a+b+c+d
}
function curry(fn){
return function sum(. args){
if(args.length<fn.length){ // Determine whether the accepted argument is smaller than the length of the function's argument
return function(){ // The parameter is not long enough. Accept the passed parameter again
returnsum(... args,... arguments) } }returnfn(... args)// Do not require change this,}}let curried = curry(sum)
console.log(curried(1) (2) (3) (4))/ / 10
console.log(curried(1.2) (2.4)) / / 9
Copy the code
Uncertain parameters
sum(1)(2)(3)(4)(5)… (n)
function curry(fn){
let parmas = []
return function sum(. args){
if(args.length){// Check whether there are parameters
parmas = [...parmas,...args]
return sum
}
return fn(parmas)
}
}
function add(arr){
return arr.reduce((acc,item) = >{
return acc+item
})
}
let curried = curry(add)
console.log(curried(1) (2) (3) (4) (10.20) ())/ / 40
// Note how the last call is used. The () call does not pass any arguments, so it will jump the judgment and call the cumulative function
Copy the code
// Define a toString method inside the method that returns the computed value
function curry(. args){
let parmas = args
function sum(){
parmas = [...parmas,...arguments]
return sum
}
sum.toString=function(){
return parmas.reduce((acc,item) = >{
return acc+item
})
}
return sum
}
console.log(curry(1) (2) (3) (10) (10.20).toString()) / / 40
Copy the code