Function corrification is the technique of turning 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

Corrification itself is fixing an expected parameter and returning a specific function to handle batch-specific requirements. This increases the applicability of the function, but also reduces its scope.

General definition

function currying(fn){
    var slice = Array.prototype.slice;
    _args = slice.call(arguments,1);
    return function(){
        var _inargs = slice.call(arguments);
        return fn.apply(null,_args.concat(_inargs))
    }
    
}Copy the code

The practicability of Currization can be seen in many ways:

Improve applicability.

General functions solve compatibility problems, but at the same time, it will also bring inconvenience to use, different application scenarios often need to transfer many parameters, has reached the specific purpose of solving. In some applications, the same rule can be used over and over again, resulting in code repetition.

function square(i){
	return i * i;
}
function dubble(i){
	return i *= 2;
}
function map(handeler,list){
	returnList. Map (handeler)} // Square map(square, [1, 2, 3, 4, 5]); map(square, [6, 7, 8, 9, 10]); map(square, [10, 20, 30, 40, 50]); // Double the map(dubble, [1, 2, 3, 4, 5]) for each item in the array; map(dubble, [6, 7, 8, 9, 10]); map(dubble, [10, 20, 30, 40, 50]);Copy the code

In the example, a generic map function is created to accommodate different application scenarios. Clearly, universality is not in doubt. Meanwhile, the same handlers are passed in repeatedly: square and dubble.

There may be more of that in applications. Of course, the enhancement of universality inevitably leads to the weakening of applicability. But we can still find a balance in the middle.

Let’s take a look at the following:

function square(i) {
    return i * i;
}

function dubble(i) {
    return i *= 2;
}

function map(handeler, list) {
    return list.map(handeler);
}

var mapSQ = currying(map, square);
mapSQ([1, 2, 3, 4, 5]);
mapSQ([6, 7, 8, 9, 10]);
mapSQ([10, 20, 30, 40, 50]);

var mapDB = currying(map, dubble);
mapDB([1, 2, 3, 4, 5]);
mapDB([6, 7, 8, 9, 10]);
mapDB([10, 20, 30, 40, 50]);Copy the code

We reduce the scope of application of the function, but at the same time improve its suitability.

Therefore, it can be seen that currization not only improves the rationality of the code, but also highlights the idea of reducing the scope of application and improving the applicability.

Here’s another example, one that’s more widely used and familiar:

function Ajax() {
    this.xhr = new XMLHttpRequest();
}

Ajax.prototype.open = function(type, url, data, callback) {
    this.onload = function() {
        callback(this.xhr.responseText, this.xhr.status, this.xhr);
    }

    this.xhr.open(type, url, data.async);
    this.xhr.send(data.paras);
}

'get post'.split(' ').forEach(function(mt) {
    Ajax.prototype[mt] = currying(Ajax.prototype.open, mt);
});

var xhr = new Ajax();
xhr.get('/articles/list.php', {},
function(datas) {
    // done(datas)    
});

var xhr1 = new Ajax();
xhr1.post('/articles/add.php', {},
function(datas) {
    // done(datas)    
});Copy the code

2 Delay execution.

Another application of Cremation is deferred execution. Continuous currification, accumulating incoming parameters, and finally execution.

See the following:

var add = function() {
    var _this = this,
    _args = arguments
    return function() {
        if (!arguments.length) {
            var sum = 0;
            for (var i = 0,c; c = _args[i++];) { sum += c; }Copy the code
            return sum
        } else {
            Array.prototype.push.apply(_args, arguments) return arguments.callee
        }
    }
}
add(1) (2) (3) (4) ();/ / 10Copy the code

Common writing:

var curry = function(fn) {
    var _args = []
    return function cb() {
        if (arguments.length == 0) {
            return fn.apply(this, _args)
        }
        Array.prototype.push.apply(_args, arguments);
        returncb; }}Copy the code

So in the case of the sum above, we can experiment with how do we write it?

3 fixed variable factors.

The Currization characteristic determines its application scenario. Fix the variable factors and pass parameters in advance to generate a more explicit application function. The most typical example is the bind function used to fix this, a mutable object.

Function.prototype.bind = function(context) {
    var _this = this,
    _args = Array.prototype.slice.call(arguments, 1);
    return function() {
        return _this.apply(context, _args.concat(Array.prototype.slice.call(arguments)))
    }
}Copy the code