Currie,

  • describe

Currization is a special kind of partial function that converts a multi-parameter function into multiple single-parameter functions, that is, converts a function with n parameters into n unary functions

  • The sample

//
function add (a, b) {
  return a + b
}
const resAdd = add(2.3)
console.log(resAdd)  / / 5
/ / curry
function currieAdd (a) {
  return function (b) {
    return a + b
  }
}
const resCurrie = currieAdd(2) (3)
console.log(resCurrie)  / / 5

Copy the code
  • General writing

The example code above is relatively simple. What if there are a dozen arguments? So you need a universal Currified script

  • The key to the code is this
  • Closure, calling the Currie function returns another function (_myFn), using the closure cache to actually perform the operation (fn) and parameters (args).
  • Pass arguments through the returned function, and determine, if enough arguments have been passed, execute function (fn) and return the result, if not, continue to return function (_myFn) to receive arguments
// Currie transforms a function
function currie (fn) {
  // Use closures to cache arguments passed in
  const args = []
  return function _myFn (arg) {
    args.push(arg)
    if (args.length === fn.length) {
      The fn function is executed and the result is returned
      return fn.apply(null, args)
    } else {
      // If the parameter is not passed, the _myfn function is returned and the call continues
      return _myFn
    }
  }
}

/ / sample 1
function add_1 (a, b) {
  return a + b
}
const currieAdd_1 = currie(add_1)
const res1 = currieAdd_1(2) (3)
console.log(res1)  / / 5

/ / sample 2
function add_2 (a, b, c, d, e) {
  return a + b + c + d + e
}
const currieAdd_2 = currie(add_2)
const res2 = currieAdd_2(1) (2) (3) (4) (5)
console.log(res2)  / / 15
Copy the code

Partial function

  • describe

Partial functions, also known as local applications, fix one or more parameters of a function, that is, convert an n-yuan function to an n-x yuan function

  • The sample

// Encapsulate an Ajax method
function ajax (url, data, callback) {... }// Call the Ajax method,
ajax('http://lyn.com', { a: 'aa' }, function () { // callback A})
ajax('http://lyn.com', { b: 'bb' }, function () { // callback B}). ajax('http://lyn.com', { y: 'yy' }, function () { // callback Y})
Copy the code

Finding that the first parameter of all the above calls is the same, it is necessary to wonder if there is a way to simplify the filling of the repeated parameter

/ / function
function partial (url) {
  return function (data, cb) {
    ajax(url, data, cb)
  }
}

// Call the partial function
const partialAjax = partial('http://lyn.com')

// Send an Ajax request
partialAjax({ a: 'aa' }, function () { // callback A})
partialAjax({ b: 'bb' }, function () { // callback B}). partialAjax({y: 'yy' }, function () { // callback Y})
Copy the code
  • General writing

Key points of code

The code for partial functions is simple, just cache the actual execution method (FN) and preset parameter (preset) using a closure and return a method to receive the remaining arguments, whose implementation is to run FN and recall the result

function partial (fn, ... preset) {
  return function (. args) {
    return fn.apply(null, preset.concat(args))
  }
}

// Example, simulated by a simple add method
function add (a, b, c, d) {
  return a + b + c + d
}
// The first two arguments passed by multiple calls are the same
// add(1, 2, 3, 4)
// add(1, 2, 5, 6)
const partialAdd = partial(add, 1.2)
const res1 = partialAdd(3.4)
console.log(res1)  / / 10
const res2 = partialAdd(5.6)
console.log(res2)  / / 14
Copy the code

The curry

  • instructions

The Collerization is actually a special case of partial functions, so in the case of anti-Collerization we’ll just call it partial functions, which I think is more appropriate

  • Contrast – partial function, anti – Coriolization

  • Partial function: Partial function is the lower order processing of higher order function, the more simple description is, reduce the generality of the function, create a more specific function, such as the above mentionedPartial functionPart of theajaxandpartialAjax
  • 1. To increase the scope of application (universality) of a method, as opposed to partial functions.
  • Generic code

Function.prototype.uncurrie = function (obj) {
  // The obj argument is the object to operate on
  // This refers to methods that obj objects need to borrow, as in the example array.prototype.push
  const fnObj = this
  return function (. args) {
    Fnobj.call (obj,... Args), see the "code parsing" section below
    return Function.prototype.call.apply(fnObj, [obj, ...args])
  }
}

// For example, export array.prototype. push methods to objects to use
const obj = { a: 'aa' }
const push = Array.prototype.push.uncurrie(obj)
push('b')
push('c')
console.log(obj)  // {0: "b", 1: "c", a: "aa", length: 2}
Copy the code
  • Code parsing

This section is responsible for parsing the generic code above

  • First of all, I don’t think this generic code is necessary, because the nature of this generic code isThe call, the applyChange the this context of a method through call and apply, so that the object can use methods that do not belong to it. This is also the essence of anti-Currization, enhancing the scope of use of methods
  • The difficulty with this generic code is thatFunction.prototype.call.apply(fnObj, [obj, ...args])This sentence is adopted by the following analysisGeneric codeIn theThe sample code
  • The following explanation should be familiar to youThe apply, callMethod source code implementation, if not familiar with please refer toJavascript Source code parsing, the call, apply two parts of the source code analysis will answer your questions
  • Start parsingGeneric codeThrough theGeneric codeIn theThe sampleCode to explain
  • Generic codeIt’s just a closure, executeArray.prototype.push.uncurrie(obj), passing an object to operate on (const obj = {a: ‘aa’}) wherefnObj = Array.prototype.pushReturn a function that accepts arguments
  • The function returns a single line of code:return Function.prototype.call.apply(fnObj, [obj, ...args]).
  • The above code can be translated as:return Function.prototype.call.apply(Array.prototype.push, [{a: 'aa'}, ...args])
  • If you do not understand the principle of call and apply, please refer to javascript source code parsing.return Array.prototype.push.call({a: 'aa'}, ... args)This sentence is equivalent to:Arrray.prototype.push.call(obj, 'b')You will see what I mean by the “statement” part at the beginning

conclusion

Currization is a special partial function. The essence of a partial function is to call a function, preset some parameters, and then return a function with fewer parameters but more specific. And against Mr Currie, don’t know why the currie, feeling should call the partial function better, the curry function and partial function instead, its essence is to enhance the using range of a function, make an object can be used to do not belong to their own way, as the apply, call the bind (also have the effect of partial function), In fact, anti-Corrification is achieved through the apply and call methods

  • Where partial functions are used

    • Where parameters need to be reduced
    • Where you need to delay the calculation
    • Function.prototype.bind is an application of partial functions
  • Where the anti-Cremation is used

    • Anticremation is used when an object needs to borrow methods from another object