Learn from article 1

Learn from article 2

I’m going to start with a general method of Currization

// Support multiple parameter passing
function progressCurrying(fn, args) {

    var _this = this
    var len = fn.length;
    var args = args || [];

    return function() {
        var _args = Array.prototype.slice.call(arguments);
        Array.prototype.push.apply(args, _args);

        // If the number of arguments is less than the original fn.length, the recursive call continues to collect arguments
        if (_args.length < len) {
            return progressCurrying.call(_this, fn, _args);
        }

        // After parameters are collected, run fn
        return fn.apply(this, _args); }}Copy the code

define

  • The 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 returns a new function that takes the remaining arguments and returns the result

  • Call a function by passing only one argument, and return a function to receive the remaining arguments and process the result (also known as partial evaluation)

    • Original function – takes four arguments and returns the result
    • Currization – Receives 1 argument and returns a function
      • This function receives the remaining arguments and returns the final result
  • Example: Change a function that passes x and y into two functions, with the outer layer passing x and the inner layer passing y

function curryingAdd(x) {
    return function (y) {
        return x + y
    }
}
Copy the code

application

(1) Parameter multiplexing

// The normal method
function meet(msg, name) {
  console.log(name, msg, "!");
}
meet("hello"."Bob");

// Currified encapsulation
function meetCur(msg) {
  return function (name) {
    console.log(name, msg, "!");
  };
}

// Get the method to auto-populate Hello
let helloMeet = meetCur("hello");
helloMeet("Lucy");
helloMeet("Bob");
helloMeet("Jack");

// Get the method to fill goodBye automatically
let byeMeet = meetCur("goodBye");
byeMeet("Lucy");
byeMeet("Bob");
byeMeet("Jack");
Copy the code

(2) Judge in advance

Originally, each call to ON required a check to see if addEventListener was supported,

After currie, you don’t need to make a judgment every time you confirm it at assignment

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); }}}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); }}; }}) ();Copy the code

(3) Bind implementation

<script>
      Function.prototype.mybind = function (context) {
        let that = this;
        // console.log("tha1t", that);
        let args = Array.prototype.slice.call(arguments.1);
        console.log(args, "args");
        return function () {
          // console.log(that, "--that", str);
            let arr = Array.prototype.concat.apply(args, arguments);
          return that.apply(context, arr);
        };
      };

      function tt(. str) {
        // console.log(this, "------", str);
        return str;
      }
      let ll = console.log;
      console.log(tt.mybind(this.234.234.43) ("00 0 -"));
      ll.mybind(this.234.234.43) ("00 0 -")
      
    </script>
Copy the code

(4) Delayed execution

The following code, as long as the argument keeps passing in, does not execute the processing result but receives the argument and returns the function.

When no more arguments are passed in, all previously received arguments are used for execution and the result is returned

var curryScore = function (fn) {
  var allScore = []; // Used to access a single value for each input
  // These are used for preprocessing
  return function () {
    if (arguments.length === 0) {
      // fn is executed when no more arguments are passed
      fn.apply(null, allScore);
    } else {
      // The parameters passed in are saved
      allScore = allScore.concat([].slice.call(arguments)); }}; };var result = 0;
// addScroe returns a function
var addScore = curryScore(function () {
  //fn
  for (var i = 0; i < arguments.length; i++) {
    result += arguments[i]; }}); addScore(3);
console.log(result); / / 0
addScore(3);
console.log(result); / / 0
addScore(3);
console.log(result); / / 0
addScore();
console.log(result); / / 9
Copy the code

General method of encapsulation

  • The complete, generic, encapsulation of a function

parsing

// Support multiple parameter passing
function progressCurrying(fn, args) {

    var _this = this
    var len = fn.length; // The number of parameters in the fn declaration
    var args = args || []; // set args to []

    return function() {
        // Gets the parameters passed in later, rounding them into the array
        var _args = Array.prototype.slice.call(arguments);
        // Integrate the previously passed parameter with the passed parameter
        Array.prototype.push.apply(args, _args);

        // If the number of arguments is less than the original fn.length, the recursive call continues to collect arguments
        if (_args.length < len) {
            // that is, return is still an append () executable.
            return progressCurrying.call(_this, fn, _args);
        }

        // After parameters are collected, run fn
        return fn.apply(this, _args); }}Copy the code

exercises

  • Simplify the problem
// Implement an add method that implements the following results
//(Simplified the online interview question)

console.log(add(1) (2) ());/ / 3
console.log(add(1.2.3) (4) ());/ / 10
console.log(add(1) (2) (3) (4) (5) ());/ / 15
Copy the code
function add(. args) {
  letret = []; ret.push(... args);if (args.length == 0) return adder();
  function adder(. arg2) { ret.push(... arg2);if (arg2.length === 0) {
      let sum = 0;
      ret.forEach((item) = > {
        sum += item;
      });
      return sum;
    } else {
      returnadder; }}return adder;
}
Copy the code
  • The original problem
// Implement an add method that satisfies the following expectations:
            // add(1)(2)(3) = 6;
            // add(1, 2, 3)= 6;
            / / add (1) (2, 3) = 6;

function add() {
  var _args = Array.prototype.slice.apply(arguments);
  // Every time _add passes an argument, it is saved to _args
  _args = _args = _args = _args = _args
  var _add = function () {
    Array.prototype.slice.apply(arguments).forEach(function (item) {
      // Another feature, confirm parameters in advance before final settlement results,
      if (!isNaN(item)) { _args.push(item); }});return _add;
  };
  // Take advantage of the toString implicit conversion feature to implicitly convert when finally executed and calculate the final value returned
    // This step solves the problem of adding () and printing the result at the same time
  _add.toString = function () {
    return _args.reduce(function (x, y) {
      return x + y;
    });
  };
  return _add;
}
Copy the code