位置: 编程技术 - 正文

JavaScript的函数式编程基础指南(JavaScript的函数库)

编辑:rootadmin

推荐整理分享JavaScript的函数式编程基础指南(JavaScript的函数库),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:JavaScript的函数中只能写一条代码语句,JavaScript的函数库,javascript的函数定义允许嵌套,JavaScript的函数中只能写一条代码语句,JavaScript的函数中只能写一条代码语句,JavaScript的函数中只能写一条代码语句,JavaScript的函数名称中可以包含$符号,javascript的函数定义允许嵌套,内容如对您有帮助,希望把文章链接给更多的朋友!

引言

JavaScript是一种强大的,却被误解的编程语言。一些人喜欢说它是一个面向对象的编程语言,或者它是一个函数式编程语言。另外一些人喜欢说,它不是一个面向对象的编程语言,或者它不是一个函数式编程语言。还有人认为它兼具面向对象语言和函数式语言的特点,或者,认为它既不是面向对象的也不是函数式的,好吧,让我们先搁置那些争论。

让我们假设我们共有这样的一个使命:在JavaScript语言所允许的范围内,尽可能多的使用函数式编程的原则来编写程序。

首先,我们需要清理下脑子里那些关于函数式编程的错误观念。

在JS界被(重度)误解的函数式编程

显然有相当一批开发者一天到晚的以函数式范式的方式使用JavaScript。我还是要说有更大量的JavaScript开发者,并不真正理解那佯做的真正意义。

我确信,导致这种局面是因为很多用于服务端的web开发语言都源自C语言,而C语言,很显然不是一种函数式编程语言。

似乎有两个层级的混乱,第一个层级的混乱我们用下面这个在jQuery中经常会用到的例子来说明:

嘿,仔细看。我传递一个匿名函数作为参数,这在JavaScript世界里被称作众所周知“CallBack”(回调)函数。

真有人会认为这就是函数式编程吗?根本不是!

这个例子展示了一个函数式语言的关键特性:函数作为参数。另一方面,这个3行代码的例子也违背了几乎所有其他的函数式编程范式。

第二个层级的混乱有点微妙。读到这里,一些追求潮流的JS开发者在暗自思考。

好吧,废话!但是我已经知道了所有关于函数式编程的知识与技能。我在我所有的项目上使用Underscore.js。

Underscore.js 是一个广受欢迎的JavaScript库,到处都在使用。举个例子,我有一组单词,我需要获得一个集合,集合里的每个元素是各个单词的头两个字母。用Underscore.js实现这个相当简单:

看!看JavaScript巫术。我正在使用这些高级的函数式应用函数,像_.map 和 _.first。你还有什么要说的,利兰(译注:作者Leland)?

尽管underscore 和 像_.map这样的函数是非常有价值的函数式范式,但是像这个例子中所采用的组织代码的方法看起来…冗长而且对于我来说太难于理解。我们真的需要这样做吗?

如果开始思考的时候多一点“函数式”的思维,可能我们能够把上面的例子改成这样:

仔细想想,在1行代码中包含了和上面5行代码同样的信息。words 和word 仅仅是参数/占位符。这个方法的核心是用一种更明显的方式组合map函数,first函数,和常量2。

JavaScript是函数式编程语言吗?

没有神奇的公式能够判定一种语言是不是“函数式”语言。有些语言很明显就是函数式的,就像另外一些语言很明显不是函数式的,但是有大量语言的是模棱两可的中间派。

于是这里给出一些常用的、重要的函数式语言的“配料”(JavaScript能实现用粗体标志)

函数是“第一等公民” 函数能够返回函数 词法上支持闭包 函数要“纯粹” 可靠递归 没有变异状态

这决不是一个排它的列表,但是我们至少要逐个讨论Javascript中最重要的三个特性,它们支撑我们可以用函数式的方式来编写程序。

让我们逐个详细的了解下:

函数是“第一等公民”

这条可能是在所有的配料中最明显的,并且可能是在很多现代编程语言中最常见到的。

在JavaScript局部变量是通过var关键字来定义的。

JavaScript中把函数以局部变量的方式定义是非常容易做到的。

这些都是事实,变量:变量add和变量even通过被赋值的方式,与函数定义建立引用关系,这种引用关系是在任何时候如果需要是可以被改变的。

当然,这没有什么特别的。但是成为“第一等公民”这个重要的特性使得我们能够把函数以参数的方式传递给另一个函数。举个例子:

JavaScript的函数式编程基础指南(JavaScript的函数库)

这是一个函数,他接受了一个二元函数f,和两个参数a,b,然后调用这个二元函数f,该二元函数f以a、b为输入参数。

这样做看起来有点笨拙,但是当把接下来的函数式编程“配料”合并考虑的时候,牛叉之处就显而易见了…

函数能返回函数(换个说法“高阶函数”)

事情开始变的酷起来。尽管开始比较简单。函数最终以新的函数作为返回值。举个例子:

这个函数(applyFirst)接受一个二元函数作为其中一个参数,可以把第一个参数(即二元函数)看作是这个applyFirst函数的“部分操作”,然后返回一个一元(一个参数)函数,该一元函数被调用的时候返回外部函数的第一个参数(f)的二元函数f(a, b)。返回两个参数的二元函数。

让我们再谈谈一些函数,例如mult(乘法)函数:

依循mult(乘法)函数的逻辑,我们可以写一个新的函数double(乘方):

这就是偏函数,在FP中经常会用到。(译注:FP全名为 Functional Programming 函数式程序设计 )

我们当然可以像applyFirst那样定义函数:

现在,我想要一个double(乘方)函数,我们换种方式做:

这种方式被称作“函数柯里化”。有点类似partial application(偏函数应用),但是更强大一点。

准确的说,函数式编程之所以强大,大部分因于此。简单和易理解的函数成为我们构筑软件的基础构件。当拥有高水平的组织能力、很少重用的逻辑的时候,函数能够被组合和混合在一起用来表达出更复杂的行为。

高阶函数可以得到的乐趣更多。让我们看两个例子:

1.翻转二元函数参数顺序

2.创建一个组合了其他函数的函数

这个例子创建了一个实用的函数,我们可以使用它来记录下每次函数调用。

词法闭包+作用域

我深信理解如何有效利用闭包和作用域是成为一个伟大JavaScript开发者的关键。那么…什么是闭包?

简单的说,闭包就是内部函数一直拥有父函数作用域的访问权限,即使父函数已经返回。<译注4>可能需要个例子。

一旦createCounter函数被调用,变量count就被分配一个新的内存区域。然后,返回一个函数,这个函数持有对变量count的引用,并且每次调用的时候执行count加1操作。

注意从createCounter函数的作用域之外,我们是没有办法直接操作count的值。Counter1和Counter2函数可以操作各自的count变量的副本,但是只有在这种非

常具体的方式操作count(自增1)才是被支持的。

在JavaScript,作用域的边界检查只在函数被声明的时候。逐个函数,并且仅仅逐个函数,拥有它们各自的作用域表。(注:在ECMAScript 6中不再是这样,因为let的引入)

一些进一步的例子来证明这论点:

关于作用域还有一些重要的事情需要考虑。例如,我们需要创建一个函数,接受一个数字(0-9),返回该数字相应的英文名称。

简单点,有人会这样写:

但是缺点是,names定义在了全局作用域,可能会意外的被修改,这样可能致使digit_name1函数所返回的结果不正确。那么,这样写:

这次把names数组定义成函数digit_name2局部变量.这个函数远离了意外风险,但是带来了性能损失,由于每次digit_name2被调用的时候,都将重新为names数组定义和分配空间。换个例子如果names是个非常大的数组,或者可能digit_name2函数在一个循环中被调用多次,这时候性能影响将非常明显。

这时候我们面临第三个选择。这里我们实现立即调用的函数表达式,仅仅实例化names变量一次,然后返回digit_name3函数,在 IIFE (Immediately-Invoked-Function-Expression 立即执行表达式)的闭包函数持有names变量的引用。这个方案兼具前两个的优点,回避了缺点。搞定!这是一个常用的模式用来创建一个不可被外部环境修改“private”(私有)状态。

简单理解JavaScript中的封装与继承特性 JavaScript中的封装封装简单地说就是让外界只能访问对象的共有变量和函数,隐藏细节和数据。js中有三种方法创建对象,分别为门户大开型、用命名规

javascript实现dom元素可拖动 摘要:最近在项目中要做一个图片预览的功能,这时候会遇到用户上传很大的图片,已经超出视图界面。最终决定做一个在固定宽和高的位置,用户可

javascript的几种继承方法介绍 1.原型链继承:构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型

标签: JavaScript的函数库

本文链接地址:https://www.jiuchutong.com/biancheng/369996.html 转载请保留说明!

上一篇:javascript 继承学习心得总结(javascript继承原理)

下一篇:简单理解JavaScript中的封装与继承特性(简单理解贴现)

  • 所得税月度申报
  • 定额税改为查账征收,可以弥补上年度亏损吗
  • 企业房产税怎么计算
  • 更改增值税申报表有退税会很麻烦吗
  • 进口货物再出口 增值税处理
  • 红字发票抵扣联丢了怎么办
  • 小企业会计准则和企业会计准则的区别
  • 子母公司有连带责任吗
  • 长期挂账的应付账款如何写申请报告
  • 客户想免费拿样
  • 把水费开成物业费发票有什么风险吗?
  • 工资分两次发的风险是什么?
  • 垫资的利息的合法区间
  • 待认证发票后面需要做附件吗
  • 出口样品可以申请专票吗
  • 一般纳税人高速公路通行费税率
  • 企业预缴多交税了如何申请退税
  • 预提工资的的计提依据
  • 与工程有关的差旅费是否可以计入在建工程呢?
  • 收到违反合同的违约金
  • php写json
  • 如何防止别人蹭热点
  • 电脑中毒如何处理
  • 商贸企业销售
  • asldrsrv.exe
  • 分类账长什么样
  • 注册资本增加了
  • 公司给员工付个税怎么算
  • 滴滴发票4月1日怎么开
  • 路由配置中network怎么用
  • 自动驾驶感知算法
  • Pytorch深度学习实战3-5:详解计算图与自动微分机(附实例)
  • py转换成exe后打开没用
  • 成本票不够怎么做账
  • 建筑公司收到的劳务费发票
  • 应付账款的平行登记
  • 错账调整分录
  • sql2005sp4
  • 增值税最高开票限额
  • mysql简单操作
  • 单位收到已交个人社保
  • 转让不动产为什么不能开全票发票
  • 未确认融资费用账务处理
  • 长期待摊费用摊销是当月还是下月
  • 投标代理费如何入账
  • 分公司财务归谁管
  • 产品成本的具体内容
  • 储备基金是什么
  • 超期应收款管控
  • 临时设施属于什么科目
  • 企业取得的财政拨款
  • 纳税人去税务局办什么
  • 销项负数发票开了需要给对方重开发票吗?
  • 预收账款账务处理流程图
  • 企业净利润的分配顺序
  • 如何搭建mybatis
  • mysql调用数据库语句
  • win10 怎么设置
  • xp怎么删除系统
  • unix怎么切换用户
  • 一台OpenSuSE系统的服务器的网络配置
  • 新买的u盘安全吗
  • ssh进入
  • windows8怎么装windows10
  • win7微软账户
  • unity控制相机
  • jquery的实现原理
  • 厦门翔安到同安有多远
  • nodejs怎么调试
  • node.js+express
  • 首次安装操作系统称为什么盘
  • three.js入门指南
  • jquery 列表实现
  • javascript标签大全
  • SQLite之SQLiteStatement
  • 如何加强税务系统财务管理工作
  • 建筑工程异地预缴税款时间限制
  • 企业滞纳金怎么算 计算公式
  • 法治税务宣传标语
  • 郑州广电地址
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设