JS中函数科里化的背景与应用实例教程

 更新时间:2022年06月06日 09:16:11   作者:程序媛徐婵  
在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术,下面这篇文章主要给大家介绍了JS中函数科里化的背景与应用实例的相关资料,需要的朋友可以参考下

背景

柯里化(Currying)是一种关于函数的高阶技术。它不仅被用于 JavaScript,还被用于其他编程语言。函数柯里化又叫部分求值,维基百科中对柯里化 (Currying) 的定义为:

在数学和计算机科学中,柯里化是一种将使用多个参数的函数转换成一系列使用一个参数的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

用大白话来说就是只传递给函数一部分参数来调用它,让它返回一个新函数去处理剩下的参数。使用一个简单的例子来介绍下,最常用的就是 add 函数了。

// add method
const add = (...args) => args.reduce((a, b) => a + b);

// 传入多个参数,执行 add 函数
add(1, 2) // 返回 3

// 假设我们实现了一个 currying 函数,支持一次传入一个参数
let sum = currying(add);
let addCurryOne = sum(1);
addCurryOne(2) // 返回 3
addCurryOne(3) // 返回 4

使用场景

柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)。柯里化不会调用函数。它只是对函数进行转换。 在平常工作中主要使用场景如下:

  • 1、延迟计算(部分求和、bind 函数)

  • 2、动态创建函数(添加监听 addEvent、惰性函数)

  • 3、参数复用(Function.prototype.call.bind(Object.prototype.toString))

JS中的函数科里化

可以对比下haskell这种天然的函数式语言,js里的珂里化实在是残缺不全...但是利用珂里化这种参数对应函数的思想,结合js的闭包特性,来实现良好的封装。 举个例子:js中最常见的dom的插入和删除。 普通写法:变量都在外部,不能确保每个remove操作都“正确”的

var append = function (parent, child) {
    parent.appendChild(child);
}
var remove = function (dom) {
    dom.remove();
}
//插入 remove(child); //删除
append(parent, child); 

文艺写法:确保了每个删除操作都会删除插入的节点。

var append = function (parent, child) {
    parent.appendChild(child);
    return function () {
        child.remove();
    }
}

//或者是这种,point free风格 
var append2 = function (parent, child) {
    parent.appendChild(child);
    return child.remove.bind(child);
}
//插入一个节点,同时返回所插入的节点的删除操作。 remove(); //删除。
var remove = append(parent, child);

总结一下就是说,这种以函作为主体,确保了函数之间不会相互干扰,尤其是在复杂的前端工程下,每一处的代码越“安全”,越独立,越能更好的拓展功能和排查问题。

经典面试题:add(1)(2)(3)

function add(seed) {
    function retVal(later) {
        return add(seed + later);
    }
    retVal.toString = function () {
        return seed;
    };
    return retVal;
}
console.log(add(1)(2)(3).toString()); // 6

add函数返回闭包retVal,在retVal中又继续调用add,最终我们可以写成add(1)(2)(3)(...)这样柯里化的形式。 每调用一次add函数,都会返回retValue函数;调用retValue函数会调用add函数,然后还是返回retValue函数,所以调用add的结果一定是返回一个retValue函数。add函数的存在意义只是为了提供闭包,这个类似的递归调用每次调用add都会生成一个新的闭包。

总结

优点:

  • 参数复用
  • 提前返回
  • 延迟计算/运行

缺点:

  • 函数柯里化可以用来构建复杂的算法 和 功能, 但是滥用也会带来额外的开销。从上面实现部分的代码中,可以看到,使用柯里化函数,离不开闭包, arguments, 递归。
  • 闭包,函数中的变量都保存在内存中,内存消耗大,有可能导致内存泄漏。
  • 递归,效率非常
  • arguments, 变量存取慢,访问性很差

我个人觉得柯里化并非是必须的,而且不熟悉的同学阅读起来可能会遇到麻烦,但是它能帮助我们理解JS中的函数式编程,更重要的是,我们以后在阅读类似的代码时,不会感到陌生。

并非“柯里化”对函数式编程有意义。而是,函数式编程在把函数当作一等公民的同时,就不可避免的会产生“柯里化”这种用法。所以它并不是因为“有什么意义”才出现的。

到此这篇关于JS中函数科里化的背景与应用的文章就介绍到这了,更多相关JS函数科里化应用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript操作表格排序实例分析

    javascript操作表格排序实例分析

    这篇文章主要介绍了javascript操作表格排序,涉及javascript数组排序与表格操作的相关技巧,需要的朋友可以参考下
    2015-05-05
  • 教你用纯JS实现语雀的划词高亮功能

    教你用纯JS实现语雀的划词高亮功能

    最近在搞一个网站,需要在内容区域实现划词高亮功能,所以下面这篇文章主要给大家介绍了关于如何用纯JS实现语雀的划词高亮功能的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • 浅谈webpack4.x 入门(一篇足矣)

    浅谈webpack4.x 入门(一篇足矣)

    这篇文章主要介绍了浅谈webpack4.x 入门(一篇足矣),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • JS 将伪数组转换成数组的实现示例

    JS 将伪数组转换成数组的实现示例

    这篇文章主要介绍了JS 将伪数组转换成数组,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • js重写方法的简单实现

    js重写方法的简单实现

    下面小编就为大家带来一篇js重写方法的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • 使用JS获取SessionStorage的值

    使用JS获取SessionStorage的值

    这篇文章给大家介绍了使用js获取sessionstorage中的值,首先获取它是为了将获得的信息输出或者alert(),其次,在静态页面中,如果使用sessionStorage就相当于在动态页面里连接了数据库一样,具体内容详情大家参考下本文
    2018-01-01
  • JavaScript promise的使用和原理分析

    JavaScript promise的使用和原理分析

    Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。由于 Promise 是 ES6 新增加的,所以一些旧的浏览器并不支持,苹果的 Safari 10 和 Windows 的 Edge 14 版本以上浏览器才开始支持 ES6 特性
    2023-04-04
  • JavaScript html5 canvas绘制时钟效果

    JavaScript html5 canvas绘制时钟效果

    这篇文章主要介绍了JavaScript html5绘制时钟效果的相关资料,使用HTML5的canvas标签和Javascript脚本,模拟显示了一个时钟,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • javascript div 遮罩层封锁整个页面

    javascript div 遮罩层封锁整个页面

    在客户端浏览器中,可以在某个时机使用javascript把一个div作为遮罩层,来封锁整个页面。
    2009-07-07
  • js获取当前页面的url网址信息

    js获取当前页面的url网址信息

    这篇文章主要介绍了通过js如何获取当前页面的url网址信息,需要的朋友可以参考下
    2014-06-06

最新评论