关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JavaScript »使用 JavaScript 进行函数式编程 (一)

    使用 JavaScript 进行函数式编程 (一)

    2015-10-01 00:00:00 出处:oschina
    分享

    本文是函数式编程系列的第一篇文章。这里我会简要介绍一下编程范式,然后会直接介绍使用 Javascript 进行函数式编程的概念,因为 JavsScript 是最被认可的函数式程序语言之一。我们鼓励读者通过参考资料部分进一步了解这一迷人的概念。

    编程范式

    编程范式是一个由思考问题以及实现问题愿景的工具组成的框架。很多现代语言都是聚范式(或者说多重范式): 他们支持很多不同的编程范式,比如面向对象,元程序设计,泛函,面向过程,等等。

    使用 JavaScript 进行函数式编程 (一)

    函数式编程范式

    函数式编程就像一辆氢燃料驱动的汽车——先进的未来派,但是还没有被广泛推广。与命令式编程相反,他由一系列语句组成,这些语句用于更新执行时的全局状态。函数式编程将计算转化作表达式求值。这些表达式全由纯数学函数组成,这些数学函数都是一流的(可以被当做一般值来运用和处理),并且没有副作用。

    使用 JavaScript 进行函数式编程 (一)

    函数式编程很重视以下值:

    函数是一等要务

    我们应该将函数与编程语言中的其他类对象同样对待。换句话说,您可以将函数存储在变量里,动态创建函数,以及将函数返回或者将函数传递给其他函数。下面我们来看一个例子…

    使用 JavaScript 进行函数式编程 (一)

    一个字符串可以保存为一个变量,函数也可以,例如:

    var sayHello = function() { return “Hello” };

    一个字符串可以保存为对象字段,函数也可以,例如:

    var person = {message: “Hello”, sayHello: function() { return “Hello” }};

    一个字符串可以再用到时才创建,函数也可以,例如:

    “Hello ” + (function() { return “World” })(); //=> Hello World

    一个字符串可以作为输入参数传给函数,则函数也可以:

        function hellloWorld(hello, world) { return hello + world() }

    一个字符串可以作为函数返回值,函数也可以,例如:

    return “Hello”;
    return function() { return “Hello”};

    高阶案例

    使用 JavaScript 进行函数式编程 (一)

    假如函数将其他函数函数作为输入参数或者作为返回值,则称之为高阶函数。刚才我们已经看过了一个高阶函数的例子。下面,我们来看一下更复杂的情况。

    例1:

    [1, 2, 3].forEach(alert);
    // alert 弹窗显示“1" 
    // alert 弹窗显示 "2" 
    // alert 弹窗显示 "3”

    例2:

    function splat(fun) {
       return function(array) {
            return fun.apply(null, array);
       };
    }
    var addArrayElements = splat(function(x, y) { return x + y });
    addArrayElements([1, 2]);
    //=> 3

    最爱纯函数

    使用 JavaScript 进行函数式编程 (一)

    纯函数不会有其他的副作用,所谓的副作用指的是函数所产生的对函数外界状态的修改。比如:

    修改某个变量 修改数据结构 对外界某个变量设置字段 抛出例外或者弹出错误信息

    最简单的例子就是数学函数。Math.sqrt(4) 函数总是返回2。他不会用到任何其他心寒信息,如状态或者设置参数。数学函数从来不会造成任何副作用。

    避免修改状态

    使用 JavaScript 进行函数式编程 (一)

    函数式编程支持纯粹的函数,这样的函数不能改变数据,因此大多用于创建不可改变的的数据。这种方式,不用修改一个已存在的数据结构,而且能高效的新建一个.

    你也许想知道,假如一个纯粹的函数通过改变一些本地数据而生产一个不可改变的返回值,是否是允许的?答案是可以。
    在JavaScript中极少的数据类型是默认是不可改变的。String是一个不能被改变的数据类型的例子:

       var s = "HelloWorld";
        s.toUpperCase();
        //=> "HELLOWORLD"
        s;
        //=> "HelloWorld"

    不可改变状态的好处

    避免混乱和增加程序的准确性:在复杂系统内,大多数难以理解的Bug是由于状态通过在程序中外部客户端代码修改而导致的。
    确立“快速简洁”的多线程编程:假如多线程可以修改同一个共享值,你不得不同步的获取值。这对专家来说都是十分乏味并且易出错的编程挑战。
    软件事务内存和Actor模型提供了直接在线程安全方式下处理修改。

    使用递归而非循环调用

    使用 JavaScript 进行函数式编程 (一)

    递归是最有名的函数式编程技术。假如您还不知道它的话,那么可以理解为递归函数就是一个可以调用自己的函数。

    替代反复循环的最经典方式就是使用递归,即每次完成函数体操作之后,再继续执行集合里的下一项,直到满足结束条件。递归还天生符合某些算法实现,比如遍历树形结构(每个树枝都是一颗小树)。

    在任何语言里,递归都是一项重要的函数式编程方式。很多函数语言甚至要求的更加严格:只支持递归遍历,而不支持显式的循环遍历。这需要语言必须保证消除了尾端调用,这是 JavasSrip 不支持的。

    惰性求值优于激进计算

    使用 JavaScript 进行函数式编程 (一)

    数学定义了很多无穷集合,比如自然数(所有的正整数)。他们都是符号表示。任意特定有限的子集都在需要时求值。我们将其称之为惰性求值(也叫做非严格求值,或者按需调用,延迟执行)。及早求值会强迫我们表示出所有无穷数据,而这显然是不可能的。

    很多语言都默认是惰性的,有些也提供了惰性数据结构以表达无穷集合,并在需要时对自己进行精确计算。

    很明显一行代码 result = compute() 所表达的是将 compute() 的返回结果赋值给 result。但是 result 的值究竟是多少只有其被用到的时候才有意义。

    可见策略的选择会在很大程度上提高性能,特别是当用在链式处理或者数组处理的时候。这些都是函数式程序员所喜爱的编程技术。

    这就开创可很多可能性,包括并发执行,并行技术以及合成。

    但是,有一个问题,JavaScrip 并不对自身进行惰性求值。话虽如此,Javascript 里的函数库可以有效地模拟惰性求值。

    闭包的全部好处

    所有的函数式语言都有闭包,然而这个语言特性经常被讨论得很神秘。闭包是一个函数,这个函数有着对内部引用的所有变量的隐式绑定。换句话说,该函数对它引用的变量封闭了一个上下文。JavaScript 中的闭包是能够访问父级作用域的函数,即使父级函数已经调用完毕。

       function multiplier(factor) {
          return function(number) {
              return number * factor;
          };
       }
      var twiceOf = multiplier(2);
        console.log(twiceOf(6));
    //=> 12

    声明式优于命令式编程

    函数式编程是声明式的,就像数学运算,属性和关系是定义好的。运行时知道怎么计算最终结果。阶乘函数的定义提供了一个例子:

    factorial(n) = 1 if n = 1

    n * factorial(n-1) if n > 1

    该定义将 factorial(n) 的值关联到 factorial(n-1),是递归定义。特殊情况下的 factorial(1) 终止了递归。

    var imperativeFactorial = function(n) {
        if(n == 1) {
            return 1
        } else {
            product = 1;
            for(i = 1; i <= n; i++) {
                  product *= i;
            }
            return product;
         }
    }
    var declarativeFactorial = function(n) {
           if(n == 1) {
                 return 1
           } else {
                 return n * factorial(n - 1);
          }
      }

    从它实现阶乘计算来看,声明式的阶乘可能看起来像“命令式”的,但它的结构更像声明式的。

    命令式阶乘使用可变值、循环计数器和结果来累加计算后的结果。这个方法显式地实现了特定的算法。不像声明式版本,这种方法有许多可变步骤,导致它更难理解,也更难避免 bug 。

    使用 JavaScript 进行函数式编程 (一)

    函数式JavaScript库

    有很多函数式库:underscore.js, lodash,Fantasy Land, Functional.js, Bilby.js, fn.js, Wu.js, Lazy.js, Bacon.js, sloth.js, stream.js, Sugar, Folktale, RxJs 等等。

    函数式程序员工具包

    map(), filter(), 和 reduce()函数 构成了函数式程序员工具包的核心。 纯高阶函数成了函数式方法的主力。事实上,它们是纯函数和高阶函数应该仿效的典型。它们用一个函数作为输入,返回没有副作用的输出。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    电脑屏幕不小心竖起来了?别慌,快捷键搞定

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    IT头条

    Synology 更新 ActiveProtect Manager 1.1 以增强企业网络弹性和合规性

    00:43

    新的 Rubrik Agent Cloud 加速了可信的企业 AI 代理部署

    00:34

    宇树科技 G1人形机器人,拉动一辆重达1.4吨的汽车

    00:21

    Cloudera 调查发现,96% 的企业已将 AI 集成到核心业务流程中,这表明 AI 已从竞争优势转变为强制性实践

    02:05

    投资者反对马斯克 1 万亿美元薪酬方案,要求重组特斯拉董事会

    01:18

    技术热点

    大型网站的 HTTPS 实践(三):基于协议和配置的优化

    ubuntu下右键菜单添加新建word、excel文档等快捷方式

    Sublime Text 简明教程

    用户定义SQL Server函数的描述

    怎么在windows 7开始菜单中添加下载选项?

    SQL Server 2016将有哪些功能改进?

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。