百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>JS教程> JavaScript 函数柯里化的学习笔记
分享文章到:

JavaScript 函数柯里化的学习笔记

发布时间:01/15 来源: 浏览: 关键词:
下面我们来看一篇关于JavaScript 函数柯里化的学习笔记,希望这篇文章能够给各位带来帮助,具体的细节步骤如下文介绍.

一. 函数柯里化的定义

函数柯里化,Function currying,又称部分求值,指的是逐步传参,逐步求解的过程。

二. 函数柯里化的实现

一个Curry函数首先会接受一些参数,接受参数之后,该函数并不会立即求值,而是继续返回另一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。

如下:

var add = (function() {
    var numArr = [];

    return function() {
        if(arguments.length === 0) {
            var result = 0;
            for(var i = 0, len = numArr.length; i < len; i++) {
                result += numArr[i];
            }
            return result;
        } else {
            // numArr.push(arguments);
            Array.prototype.push.apply(numArr, arguments);
        }
    }
})();

/* =============== 客户端调用 =============== */
add(21);
add(2);

console.log(add()); // 23

三. 通用的柯里化函数

柯里化的操作可以概括为:

接受一个函数;
返回一个只接收一个参数的函数。
通用的柯里化函数可以如下:

var currying = function(fn) {
    var args = [];

    return function() {
        if(arguments.length === 0) {
            // 进行真正的求值计算
            return fn.apply(this, args);
        } else {
            // 保存调用的所有参数
            Array.prototype.push.apply(args, arguments);
            return arguments.callee;
        }
    }
};

那么上面的add函数可以改写成如下:

var add = (function() {
    var result = 0;
    return function() {
        for(var i = 0, len = arguments.length; i < len; i++) {
            result += arguments[i];
        }
        return result;
    }
})();
调用结果如下:

/* =============== 客户端调用 =============== */
var addCurrying = currying(add); // 转换成currying函数
addCurrying(21);
addCurrying(2);

console.log(addCurrying()); // 23

四. 反柯里化

反柯里化与柯里化相反,就是把原来已经固定的参数或者this上下文等当作参数延迟到未来传递。

反柯里化的作用在与扩大函数的适用性,使本来作为特定对象所拥有的功能的函数可以被任意对象所用。更通俗的解释说反柯里化是 函数的借用,是函数能够接受处理其他对象,通过借用泛化、扩大了函数的使用范围。

反柯里化的三种写法如下:

4.1 写法一:

var uncurrying= function (fn) {
    return function () {
        var context = [].shift.call(arguments);
        return fn.apply(context, arguments);
    }
};

4.2 写法二:

var uncurrying = function(fn) {
    return function() {
        return Function.prototype.call.apply(fn, arguments);
    }
}

4.3 写法三:

var uncurrying = Function.prototype.bind.bind(Function.prototype.call);
4.4 反柯里化的实际调用示例:

/* =============== 客户端调用 =============== */
var push = uncurrying(Array.prototype.push); // 反柯里化

var arr = {};
push( arr , ["Bob" , "Jenny" , "Tom"] );

console.log(arr); // Object {0: "Bob", 1: "Jenny", 2: "Tom", length: 3}

五. 柯里化的适用场景

当一个函数传递的参数绝大多数是相同的,且函数结果的可以推迟到参数耗尽时才计算,那么该函数就适合使用柯里化。

六. 柯里化的性能分析

柯里化肯定会有一些性能开销,具体性能分析如下:

存取 arguments 对象通常要比存取命名参数要慢一些;
一些老版本的浏览器在 arguments.length 的实现上相当慢;
使用 fn.apply() 和 fn.call() 要比直接调用 fn() 要慢点;
创建大量嵌套作用域和闭包会带来开销。
七. 总结

函数柯里化允许和鼓励你分隔复杂功能变成更小更容易分析的部分。这些小的逻辑单元显然是更容易理解和测试的,然后你的应用就会变成干净而整洁的组合,由一些小单元组成的组合。

但是函数柯里化也会带来一些性能开销。在项目开发中斟酌使用。

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有15人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板