函数的柯里化

柯里化就是将一个接收“多个”参数的函数拆分成一个或者许多个接收“单一”参数的函数。

特点:

  • 固定易变因素
  • 延迟计算
  • 提前绑定好函数里面的某些参数,达到参数复用的效果,提高了适用性
function add(a, b) {
    return a + b;
}

function curryingAdd(a) {
    return function(b) {
        return a + b;
    }
}

add(1, 2); // 3
curryingAdd(1)(2); // 3
function curryingHelper(fn) {
    var _args = Array.prototype.slice.call(arguments, 1);
    return function() {
        var _newArgs = Array.prototype.slice.call(arguments);//默认去掉第一个数
        var _totalArgs = _args.concat(_newArgs);
        return fn.apply(this, _totalArgs);
    }
}
function showMsg(name, age, fruit) {
    console.log('My name is ' + name + ', I\'m ' + age + ' years old, ' + ' and I like eat ' + fruit);
}

var curryingShowMsg1 = curryingHelper(showMsg, 'dreamapple');
curryingShowMsg1(22, 'apple'); // My name is dreamapple, I'm 22 years old,  and I like eat apple

var curryingShowMsg2 = curryingHelper(showMsg, 'dreamapple', 20);
curryingShowMsg2('watermelon'); // My name is dreamapple, I'm 20 years old,  and I like eat watermelon

柯里化的应用##

延迟执行

function hello(name) {
    console.log('Hello, ' + name);
}
setTimeout(hello('dreamapple'), 3600); //立即执行,不会在3.6s后执行
setTimeout(function() {
    hello('dreamapple');
}, 3600); // 3.6s 后执行

然,在ES5里面,我们也可以使用函数的bind
方法,如下所示:

setTimeout(hello.bind(this, 'dreamapple'), 3600); // 3.6s 之后执行函数

我们本篇文章是讨论函数的柯里化,当然我们这里也可以使用函数的柯里化来达到这个效果:

setTimeout(curryingHelper(hello, 'dreamapple'), 3600); // 其中curryingHelper是上面已经提及过的

高阶函数(high-order function)##

高阶函数就是操作函数的函数,它接受一个或多个函数作为参数,并返回一个新的函数.

我们来看一个例子,来帮助我们理解这个概念.就举一个我们高中经常遇到的场景,如下:

f1(x, y) = x + y;
f2(x) = x * x;
f3 = f2(f3(x, y));

我们来实现f3函数,看看应该如何实现,具体的代码如下所示:

function f1(x, y) {
    return x + y;
}

function f2(x) {
    return x * x;
}

function func3(func1, func2) {
    return function() {
        return func2.call(this, func1.apply(this, arguments));
    }
}

var f3 = func3(f1, f2);
console.log(f3(2, 3)); // 25

性能###

柯里化肯定会有一些开销(函数嵌套,比普通函数占更多内存),但性能瓶颈首先来自其它原因(DOM 操作等)。

从另外一个角度分析,不管你用不用柯里化这个思维,你的代码很可能已经步入了更复杂的模式,会有更大的开销。

Function.prototype.toString()##

该 toString() 方法返回一个表示当前函数源代码的字符串。

Number.prototype.valueOf()##

该方法通常是由 JavaScript 引擎在内部隐式调用的,而不是由用户在代码中显式调用的。

var numObj = new Number(10);
console.log(typeof numObj); // object

var num = numObj.valueOf();
console.log(num);           // 10
console.log(typeof num);    // number

参考:https://segmentfault.com/a/1190000006096034
https://segmentfault.com/a/1190000003733107

你可能感兴趣的:(函数的柯里化)