宝哥软件园

探索JavaScript函数式编程的乐趣

编辑:宝哥软件园 来源:互联网 时间:2021-09-20

编程范例

编程范式是由思考问题和实现问题愿景的工具组成的框架。许多现代语言是多范式(或多范式):它们支持许多不同的编程范式,如面向对象、元编程、函数式、面向过程等。

函数式编程范式

功能编程就像是氢燃料——驱动的高级未来派汽车,但并没有得到广泛普及。与命令式编程相反,它由一系列语句组成,用于在执行过程中更新全局状态。函数式编程将计算转换为表达式求值。这些表达式都是由纯数学函数组成的,是一级的(可以作为通值使用和处理),没有副作用。

函数式编程非常重视以下价值观:函数是第一要务。

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

字符串可以保存为变量,函数也可以。比如复制代码如下: var say hello=function(){ return " hello " };字符串可以保存为对象字段或函数。例如,复制代码如下: varperson={ message 3360 " hello ",say hello 3360 function(){ return " hello " };字符串只有在可以重用时才能被创建,函数也是如此。比如复制代码如下:“hello”(function(){ return“world”})();//=Hello World一个字符串可以作为输入参数传递给一个函数,那么这个函数也可以:复制代码如下: function Hello World(Hello,world) {return helloworld ()}一个字符串可以作为函数返回值,并且这个函数还可以,例如:

返回“你好”;return函数(){返回“Hello”};高阶情况

如果一个函数将其他函数作为输入参数或返回值,则称为高阶函数。我们刚刚看到了一个高阶函数的例子。接下来,我们来看一个更复杂的情况。例1:

[1, 2, 3].forEach(警报);//告警弹出显示“1”//告警弹出显示“2”//告警弹出显示“3”示例2:

函数splat(fun){ return fun(array){ return fun . apply(null,array);};}var addArrayElements=splat(函数(x,y) { return x,y });addArrayElements([1,2]);//=3最喜欢的纯函数。

纯函数没有其他副作用,所谓副作用是指函数产生的函数外部状态的修改。例如:

修改变量和修改数据结构会在外部变量的设置字段上引发异常或弹出错误消息。最简单的例子是数学函数。Math.sqrt(4)函数总是返回2。他不会使用任何其他令人不寒而栗的信息,如状态或设置参数。数学函数从来不会引起任何副作用。

避免修改状态。

函数式编程支持纯函数,不能改变数据,所以多用于创建不可改变的数据。这样,可以高效地创建现有的数据结构,而无需修改它。您可能想知道是否允许纯函数通过更改一些本地数据来产生不可更改的返回值。答案是肯定的。默认情况下,JavaScript中很少有数据类型是不可变的。字符串是不能更改的数据类型的一个示例:

var s=' HelloWorlds . touppercase();//=' HELLOWORLD ' s;//='HelloWorld '状态不变的好处。

避免混乱,增加程序的准确性:在复杂的系统中,大多数难以理解的bug都是由程序中外部客户端代码的修改引起的。建立“快速简洁”的多线程编程:如果多线程可以修改同一个共享值,就得同步取值。对于专家来说,这是一个乏味且容易出错的编程挑战。软件事务内存和Actor模型以线程安全的方式直接处理修改。

使用递归而不是循环调用。

递归是最著名的函数式编程技术。如果你还不知道的话,可以理解为递归函数是一个可以自己调用的函数。替换重复循环最经典的方法是使用递归,即每次完成函数体操作后,继续执行集合中的下一项,直到满足结束条件。递归也自然符合一些算法,比如遍历树结构(每个分支都是一棵小树)。递归是任何语言中一种重要的函数式编程方法。许多函数式语言甚至更严格:它们只支持递归遍历,而不支持显式循环遍历。这需要语言确保消除尾端调用,这是JavasSrip不支持的。

惯性评估优于激进计算。

数学定义了很多无穷集合,比如自然数(都是正整数)。它们都是象征性的表现。任何有限子集在需要时都会被评估。我们称之为懒惰评估(也称为松懈评估,或按需调用并延迟执行)。早期评估会迫使我们表达所有无限的数据,这显然是不可能的。默认情况下,许多语言都是惰性的,有些语言还提供惰性数据结构来表达无限集合,并在需要时精确计算自己。显然,一行代码result=compute()表示compute()的返回结果被赋给了result。但是结果的价值只有在使用的时候才有意义。可以看出,策略的选择将大大提高性能,尤其是在链处理或数组处理中使用时。这些是函数式程序员最喜欢的编程技术。这打开了许多可能性,包括并发执行、并行技术和合成。但是,有一个问题是JavaScrip不会懒洋洋地评估自己。说了这么多,Javascript中的函数库可以有效的模拟懒惰求值。关闭的所有好处。

所有函数式语言都有闭包,但是这种语言特性经常被神秘地讨论。闭包是一个函数,它隐式绑定到内部引用的所有变量。换句话说,函数关闭了它所引用的变量的上下文。JavaScript中的闭包是一个可以访问父作用域的函数,即使父函数已经被调用。

函数乘数(因子){返回函数(数){返回数*因子;};} var twiceOf=乘数(2);console . log(Twiceof(6));//=12声明式编程优于命令式编程。

函数式编程是声明性的。就像数学运算一样,属性和关系都定义得很好。运行时知道如何计算最终结果。阶乘函数的定义提供了一个例子:阶乘(n)=1如果n=1 n *阶乘(n-1)如果n=1这个定义将阶乘(n)的值与阶乘(n-1)联系起来,这是一个递归定义。在特殊情况下,阶乘(1)终止递归。

var PriceIveFactory=function(n){ if(n==1){ return 1 } else { product=1;for(I=1;I=n;I){ product *=I;}退回产品;} } var declarativeFactorial=function(n){ if(n==1){ return 1 } else { return n *阶乘(n-1);}}从它的阶乘计算来看,声明性阶乘可能看起来像“命令式”,但它的结构更像是声明性的。命令阶乘使用变量值、循环计数器和结果来累积计算结果。此方法显式实现特定的算法。与声明性版本不同,该方法有许多可更改的步骤,这使得理解和避免错误变得更加困难。

函数式JavaScript库

有很多函数库:下划线. js、lodash、fantasyland、functional.js、bilby.js、fn.js、wu.js、lazy.js、bacon.js、slow.js、stream.js、sugar、folktale、rxjs等等。功能程序员工具包。

Map()、filter()和reduce()函数构成了函数式程序员工具包的核心。纯高阶函数成为泛函方法的主力军。事实上,它们是纯函数和高阶函数应该模仿的典型例子。它们将函数作为输入,并返回没有副作用的输出。这些JavaScript函数对于每一个函数程序都非常重要。它们可以消除循环和语句,使代码更加清晰。这些是实现ECMAScript5.1的浏览器的标准,它们只处理数组。每次调用都会创建并返回一个新数组。现有数组不会被修改。但等一下,远不止这些。它们还将函数作为输入参数,通常是匿名函数作为回调。他们将遍历整个数组,并将回调函数应用于每个项目!myArray=[1,2,3,4];newArray=myArray.map(函数(x){ return x * 2 });console . log(my array);//Output: [1,2,3,4]console . log(new array);//Output: [2,4,6,8]除了这三个函数之外,几乎每个函数应用程序中都可以嵌入很多函数:foreach()、concat()、reverse()、sort()、everyone()以及some()JavaScript的聚合范式。

当然,JavaScript并不是严格意义上的函数式编程语言,这也促进了其他范式的使用:命令式编程:基于详细操作描述的编程;基于原型的面向对象编程;基于原型对象及其实例的元程序编程:操纵JavsScript执行模型的编程模式。元编程的一个很好的定义是“编程发生在你写代码去做某事的时候,而元编程发生在你写代码去改变解释某事的方式的时候。

以上就是如何使用JavaScript函数式编程,希望对大家的学习有所帮助。

更多资讯
游戏推荐
更多+