Simple and crude elaborate javascript to achieve function and anti curried currying

    Function currying (black question mark face)? ? ? Currying (black question mark face)? ? ? Properly properly Chinese translation déjà vu; Let's take a look at what is the function currying:

    Wikipedia explains that: the function of receiving a plurality of parameters into a single receiving parameter (first parameter of the first function) of the function, and returns the remaining parameters and accepts results returned in the art the new function. It was proposed by the mathematician Haskell Brooks Curry, and to curry name. 

    Concepts are often dry and difficult to understand, let's employer words to explain is this: if we are not sure how many parameters of this function, we can give it a pass parameters, and then by JS closure (Closed Should understand JS package, first closure learning knowledge come to learn this post   https://www.cnblogs.com/dengyao-blogs/p/11475575.html  ) returns to a function, in addition to the first internal function receives a parameter outside and outputs the remaining operating parameters, this is the function of currying;

    Small example:

      Scene (demand):

      Well-known programmer overtime every day, or more, if we need to calculate a programmer overtime every day, our first reaction should be like this;

     

var overtime=0;
function time(x){
    return overtime+=x;
}

time(1);  //1
time(2);  //3
time(3);  //6

 

 

 

  The code above is certainly no problem, but you need to call every day count plus what time of day, a lot of trouble, and each function should be called once a certain operation, if the amount of data is huge, there may be risks of performance, then there lazy and can not be solutions to problems? some!

  

function time(x){
  return function(y){
        return x+y;
    }      
}

var times=time(0);
times(3);

  But the above code is still a problem, a lot of time in the actual development of our parameters are uncertain, the above code is simple to achieve the basic operation curried, but for uncertain parameter case is not treated; therefore there limitations function parameters; however, we know from the above basic code function currying Gesha mean; when a function call is only allowed to pass in a parameter, and then returns through the inner closure function to process and receive the remaining argument, the function returns remember the time of the first parameter by means of the closure;

  Let us transform what the code:

//   first define a variable receive function 
var Overtime = ( function () {
 // definition of an array for receiving parameters 
  var args = [];
 // here using a closure, internal and external function calls the function returns a 
  return  function () {
  // arguments browser built-in objects, specifically designed to receive parameters 
  // If the length parameter is 0 i.e. no arguments 
    IF (the arguments.length === 0 ) {
    // define variables for accumulating 
      var time = 0 ;
    // cycle accumulation, and i is compared with the length of the args 
      for ( var i = 0, L = args.length; i <L; i ++ ) {
    // for accumulation equivalent to args + Time = Time [i] 
        Time + =args [I]; 
      } 
    // return the result of the accumulated 
      return Time;
    // if arguments object parameter length is not zero, i.e., when the parameter has 
    } the else {
    // empty array defined arguments parameter is added as an array entry, a first Old args argument as a change in this point, the second argument as arguments the remaining parameters were added to an empty array of the array 
      [] .push.apply (args, arguments); 
    } 
  } 
}) (); 

Overtime ( 3.5 of);     // The first day 
Overtime (4.5);     // The next day 
Overtime (2.1);     // day 
// ... 

console.log (Overtime ());     // 10.1

 

  After the code transformation we have achieved function, but this is not a complete implementation of curried function, then we have to realize how complete it? Let us introduce a generic implementation:

  Universal implementation:

// definition method currying, to pass a parameter 
var as currying = function (Fn) {
  // remaining empty parameter defines the number of assembly arguments object 
  var args = [];
  // use the closure function returns a handle remaining parameters 
  return  function ( ) {
    // if arguments parameter length is 0, i.e. there is no remaining parameters 
    IF (the arguments.length === 0 ) {
    // perform the above process 
      return fn.apply ( the this , args) 
    } 
    the console.log (arguments) 
  // If the parameter is not the length of the arguments is 0, i.e. there are remaining parameters 
  // Adds an array on a prototype array of objects, Apply this point is used to change the args 
  // a [] .slice.call (arguments) is added to the array array prototype
   Array.prototype.push.apply (args, []. Slice.call (arguments))
     // args.push ([]. Slice.call (arguments)) 
    the console.log (args)
  // returned here arguments.callee a closure function returns, the callee is a property of the object inside the arguments for function returns the object being performed 
    return the arguments.callee 
  } 
} 
  // called here currying method and passing the add function, the result will be an internal function returns closure 
  var s = as currying (the Add);
  // call the function of internal closure, when there will be parameter args parameter gradually added to the array, the parameter to be passed when there is no direct call 
  // called when chaining support 
  s (1) (2) (3 ) ();
 // can also pass a plurality of parameters disposable 
   S (l, 2,3 ); 
  the console.log (S ());

 

  

  JS function currying advantages:

    1. The delay may be calculated, i.e., if the incoming call parameters currying function is not invoked, will add to the parameters stored in the array, until there is no incoming call parameters;

    2. multiplexing parameter, the parameter when calling the same function, and the vast majority of transmission is the same, then the function may be a good candidate for currying.

 

 

 
  Relative things in the world, because there must be fruit, of course, there are bound to anti-currying currying;

  Anti-currying ( uncurrying ), that is, with the meaning of currying opposite from the literal meaning is concerned; in fact the real anti-currying role is to expand the scope of application, that when we call a method, no need to consider the object itself in the design process, there is no such method, as long as the method is applicable to it, we can use; (this refers to dynamic languages duck type of thinking)

 

  Before learning JS anti curried, we first learn about the type of thinking duck dynamic languages, to help us better understand:

  Dynamic languages ​​duck type thinking (Wikipedia explanation):

    In programming, the type of duck (duck typing) is a dynamic type style.

    In this style, a semantic object is active, not by inheritance from a particular class or implement particular interface, but is determined by the current set of methods and properties.

    The name comes from the duck test the concept proposed by James Whitcomb Riley, "duck test" may put it this way:

      When you see a bird walks like a duck, swim like a duck and quacks like a duck, then this bird can be called a duck.

  Theoretical explanation often dry and difficult, and replaced with the words of people is: You are your mother's son / daughter, no matter whether you are the best, is beautiful, as long as you own your mother, then you are your mother's son / daughter; duck type is replaced, as long as you croak, walks like a duck, as long as you have a behavior like a duck, whether you are not a duck, then you can be called a duck;

    There are a lot of ducks in Javascript reference types, such as when we were assigned to a variable, is clearly no need to consider the type of object, it is because of this, Javascript was more flexible, so that Javascript is a typical dynamic the type of language;

  Anti-currying, we look at how the duck type of reference:

  

// add the function prototype object uncurring method 
Function.prototype.uncurring = function () {
 // change this point of     
// where this point is Array.prototype.push 
  var Self = this ;
     // here for closure returns the internal function execution 
  return  function () {
     // create a variable, add and delete the first parameter in the prototype object above shift array 
    // change this point is the array arguments 
    var obj = Array.prototype.shift.call ( arguments);
     // finally executed and returns to the method of changing the directivity of obj i.e. arguments 
   // and passing arguments as parameters 
    return self.apply (obj, arguments); 
  }; 
}; 

// add array prototype object methods uncurrying
var Push = Array.prototype.push.uncurring (); 

// test 
// anonymous function self-executing 
( function () {
     // Push is a function of the method here 
    // equivalent parameters passed two arguments and 4 parameter, but the shift in the above methods remove the first parameter, where the parameter arguments are intercepted, so finally only actually passed in. 4 
  Push (arguments,. 4 ); 
  the console.log (arguments); // [. 1, 2, 3, 4] 
// anonymous function calls from and into parameters 1,2,3 
}) (1, 2, 3)

  Here we can think about arguments is an object parameter receiving, there is no push method, then calls the push method arguments why can it?

  This is because the code var push = Array.prototype.push.uncurring (); added to the push method a prototype object uncurring array method, and then performing a method anonymous function push (arguments, 4); when in a substantially the above method calls added to the prototype object of uncurring function returns a closure and method of internal functions are executed on the shift method will Array prototype object during the execution of the  push (arguments, 4); the arguments taken, so in fact, the actual method call is a push (4), so the end result is [1,2,3,4]

 

Guess you like

Origin www.cnblogs.com/dengyao-blogs/p/11495861.html