The function is currified

Definition:

Is to transform a function that takes multiple arguments into a function that can be passed in one argument at a time.

Principle:

The arguments passed in are retained through closures, and in subsequent calls, if there are not enough arguments, a function is returned until the call is executed.

Function:

Some parameters of a function can be solidified ahead of time.

Such as the encapsulation of network request methods

  1. Start with a basic Request-API
Const request = (method, url, body) => {// }Copy the code

As we all know, network requests are those kinds, the most common ones are GET and POST. But each time this method is called, the following is required

request('get', 'url1', { a: 1 })

request('post', 'url2', { b: 2 })
Copy the code

The method parameter must be passed every time, which is troublesome and has the probability of spelling errors. Therefore, to improve the experience, we hope that you can pass this parameter once and save it internally instead of passing it every time.

  1. Solidify method parameters to provide more convenient GET and POST methods
const get = (url, body) => { return request('get', url, body) } const post = (url, body) => { return request('post', Get ('url1', {a: 1}) post('url2', {a: 1})Copy the code

Here’s another example:

Here is a basic method of checking data, taking the value val and type type

Const isType = (val, type) = > {return Object. The prototype. ToString. Call (val) = = = ` `} ${type} [Object] / / usage is as follows isType(1,"Number") isType(2,"String")Copy the code

But the data types in JS are fixed. The isType type parameter is the same as the method parameter above, and can be solidified in time.

const isType = (type)=>{ return (val)=>{ return Object.prototype.toString.call(val) === `[object ${type}]` } } const IsArray = isType('Array') const isString = isType('String') const isNumber = isType('Number') // The console. The log (isArray ([1, 2]) console. The log (isString (111))Copy the code

Fixed parameters

None of these examples of how to handle function arguments, while they all work, is generic enough.

The number of calls is first supported only a limited number of times (2), which is not easy to satisfy if it is multiple.

For example, it is difficult to deal with the following parameter summation scenario:

Requirement: change the summation function into parameters and pass them in batches. Once the parameters are complete (==5), the summation will be calculated immediately

Const sum = (a, b, c, d, e) = > {return a + b + c + d + e} / / expected effect sum (1) (2) (3) (4) (5) / / 15Copy the code

Finally in their own unremitting efforts, out of a bowl of delicious spaghetti…

const sum = (a)=>{

         return (b)=>{

            return (c)=>{

                 return (d)=>{

                     return (e)=>{

                         return a + b + c + d + e

                     }

                 }

             }

         }

 }
Copy the code

Just kidding, to implement a generic Currie tool function for multi-parameter scenarios, you can do this:

const curring = (fn,argArr = [])=>{ const argLen = fn.length; return (... args)=>{ argArr.push(... args) if(argArr.length < argLen){ return curring(fn,argArr) }else{ return fn(... argArr) } } } // console.log(curring(sum)(1)(2)(3)(4)(5))Copy the code

However, the implementation of recursive collection of parameters in this version is a bit problematic, because curring itself only needs one FN parameter, the extra argArr parameter, just by passing down the recursive way to hold an internal variable, can be solved by closure.

const curring = (fn) => { const argLen = fn.length; const argArr = []; const callFn = (... args) => { argArr.push(... args) if (argArr.length < argLen) { return callFn } else { return fn(... argArr) } } return callFn } // console.log(curring(sum)(1)(2)(3)(4)(5))Copy the code

This results in a more perfect function parameter, curring.

In addition, the author encountered a more difficult problem in an interview: if the number of parameters of a function is not fixed, how to achieve coriolization?

Unfixed parameter

// Implement an add method that meets the following expectations: add(1)(2)(3) // 6; add(1, 2, 3)(4) // 10; add(1)(2)(3)(4)(5) // 15;Copy the code

This demand, in fact, there are very few actual application scenarios, at most the interview to ask, in the spirit of service in the end, here also talk about.

First, this requirement is theoretically impossible. Because you never know when the higher-order function stops calling, you can’t calculate the final sum, but since the interviewer is taking the test, it certainly makes sense. You need to limit the use scenario, what kind of scenario is that? Let’s take a look at some code

function add(){}

console.log(add) // [Function: add]
Copy the code

With a slight alteration,

function add(){}

add.toString=function(){
    return 5;
}

console.log(add) // [Function: add]

console.log(add + 0) // 5
Copy the code

+0 changes the output of the result quite a bit. This is where implicit conversions come in: when a valueOf an object type (array, object, function, etc.) participates in a primitive operation, such as an arithmetic or logical operation, we try to call toString or valueOf to get a primitive value. See the author previously written this article from the [ECMA-262 language specification], interpretation of JS forced data type conversion rules – digging gold.

Imagine that the sum function returns a function that overrides toString, triggering the summation in toString at the end of the implicit conversion. So to translate the idea into code, it is the following code:

function sum(... args1){ const args = [...args1] function returnFn(... args2){ args.push(... args2) return returnFn } returnFn.toString = function(){ return args.reduce((a,b)=>a+b,0) } return returnFn } console.log(sum(1)(2)(3)(4)(5) + 0) // 15Copy the code

Therefore, when asked this question in the interview, remind the examiner first, need to limit the use scenario, that is, need to happen implicit conversion, can be effective.

That’s all. Thanks for reading.