Senior Advanced js the function currying

Currying function is a function to optimize the way all programming languages ​​respected, functions, currying is that you write js basis elegant function.

concept

In computer science, curried (Currying) is a function of receiving the plurality of parameters is converted into a function that accepts a single parameter (first parameter of the first function), and accepts the new function returns the remaining arguments and returns the result of technology.
For example: We find (a + b) * c If common way to achieve f (a, b, c) , by currying method: f (a) (b) © get this call format.

The principle

  • Closure to save parameters;
  • Higher-order functions to achieve operational;

For example, the most simple example: seeking (15 + 3) * value of 4

let calcu = (a, b, c) => (a+b)*c;
        function curry(fn, args){
            let len = fn.length;
            let _this = this;
            let _args = args || [];
            return function(){
                let args = Array.prototype.slice.apply(arguments);
                args = Array.prototype.concat.call(_args, args);
                // 当接收到的参数小于fn所需参数个数时,继续接收参数
                if(args.length < len){
                    return curry.call(_this, fn, args);
                }
                return fn.apply(this, args);
            }
        }
        let add = curry(calcu);
        console.log(add(15)(3)(5)); //72

In the above code, we can not use it curry function disposable three parameters, but slowly reception, when the received parameter reaches found three return results. This parameter is multiplexed (by way of example we can see, the main reason for this feature is achieved by using a closure, the received parameter stored in _args, the closure due to these parameters after executing the function is not He was released.

The above method of curry, read each time the fn call with args parameter to save and read this parameter args connect with all parameters _args currently has a total of using concat method, when the number of parameters in line with fn when the number of parameters required, the call fn.

Feature

  • Multiplexing parameters: the principle is the use of closures, let us come to the front of the transmission parameters not to be released.
  • Confirmed in advance: for some method to rewrite the global use of curried characteristics, in fact, such a method determined in advance which ones will avoid every judge.
  • Run Delay: using the closure to separate the definition and execution environment functions.

Case multiplexing parameters:

// 正常正则验证字符串 reg.test(txt)

// 函数封装后
function check(reg, txt) {
    return reg.test(txt)
}

check(/\d+/g, 'test')       //false
check(/[a-z]+/g, 'test')    //true

// Currying后
function curryingCheck(reg) {
    return function(txt) {
        return reg.test(txt)
    }
}

var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)

hasNumber('test1')      // true
hasNumber('testtest')   // false
hasLetter('21212')      // false

In advance to confirm:

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);
    }
}

Delayed run:

Function.prototype.bind = function (context) {
    var _this = this
    var args = Array.prototype.slice.call(arguments, 1)
 
    return function() {
        return _this.apply(context, args)
    }
}

Achieve optimal function of currying

Function currying method is a more difficult application, the most important is to understand the principle you to read the source code accessible, here is a method to achieve the best curried, he may back off emergency

// 支持多参数传递
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);

        // 如果参数个数小于最初的fn.length,则递归调用,继续收集参数
        if (_args.length < len) {
            return progressCurrying.call(_this, fn, _args);
        }

        // 参数收集完毕,则执行fn
        return fn.apply(this, _args);
    }
}
Published 69 original articles · won praise 6 · views 1863

Guess you like

Origin blog.csdn.net/weixin_40073115/article/details/103940769