当前位置: 首页 > Web前端 > vue.js

轻松玩转函数式编程

时间:2023-03-31 23:31:02 vue.js

最近和一些同学讨论函数式编程。很多同学总觉得听上去很高级,但是上手却无从下手。于是抽空整理了一下日常工作中用到的函数式编程案例和思路。相信看完这篇文章,大家可以快速上手函数式编程。函数式编程目前使用范围非常广泛,几乎在所有常用的框架和语言中都能看到它的身影。前端框架:react和vue中hooks的使用。打包工具:webpack的webpack-chain用法。工具库:underscore、lodash、ramda。部署方式:无服务器。后端:java、c#中的lamda表达式。本文将在以下3个部分深入探讨函数式编程。编程范式函数式编程函数式编程常见案例编程范式编程范式是指描述程序员对程序执行的看法的编程风格。在编程世界中,同一个问题可以从多个角度来分析和解决,而这些不同的解决方案对应着不同的编程风格。常见的编程范式有:命令式编程面向过程编程C面向对象编程C++、C#、Java声明式编程函数式编程Haskell命令式编程命令式编程是使用最广泛的编程风格,它站在计算机上,从不同的角度思考问题perspective,主要思想是关注计算机执行的步骤,即告诉计算机先做什么,然后一步步做什么。由于需要控制的步骤较多,命令式编程一般具有以下特点:控制语句循环语句:while,for条件分支语句:ifelse,switch无条件分支语句:return,break,continue变量赋值语句根据这些特性,我们来分析一个命令式编程案例://需求:过滤掉数组中奇数的子集constarray=[1,2,3,4,5,6,7,8,9];//Step1:定义执行结果变量letreult=[];//Step2:控制程序循环调用for(leti=0;iitem%2!==0);可以看出,声明式编程没有多余的操作步骤,代码量非常少,非常语义化。当我们读到filter的时候,自然知道我们在做筛选。再来看另外一种情况:#使用sql语句查询id为25的学生select*fromstudentswhereid=25在上面的代码中,我们只是告诉计算机我要查找id为25的学生,并且计算机可以返回给我们相应的数据,至于怎么查出来的,我们不需要关心,只要结果正确即可。除了上面的例子,还有很多声明式编程的情况:html用来声明网页的内容。css用于声明网页中元素的外观。一个正则表达式,指定要匹配的规则。结合以上案例,我们总结一下声明式编程的优缺点:声明式编程不需要编写复杂的操作步骤,可以大大减轻开发人员的工作量。声明式编程的具体操作统一管理,可以减少重复性工作。声明式编程的底层逻辑是不可控的,不适合更精细的优化。函数式编程函数式编程是一种声明式编程。它的主要思想是把计算机的运算看作函数的计算,即将程序问题抽象成数学问题来解决。在函数式编程中,我们可以充分利用数学公式来解决问题。也就是说,任何问题都可以通过函数(加减乘除)和数学规律(交换律、结合律等)一步步计算,最终得到答案。在函数式编程中,所有的变量都是唯一值,就像数学中的代数x和y一样,要么没有解出,要么已经解出一个固定值,所以对于:x=x+1的自增是非法的,因为修改了代数值,不符合数理逻辑。另外,严格意义上的函数式编程不包括循环、条件判断等控制语句。如果需要条件判断,可以使用三元运算符代替。我们在文章开头提到了webpack-chain,我们来看看://使用webpack-chain来编写webpack配置。constConfig=require('webpack-chain');constconfig=newConfig();config..entry('index').add('src/index.js').end().output.path('dist').filename('my-first-webpack.bundle.js');config.module.rule('compile').test(/.js$/).use('babel').loader('babel-loader')module.exports=配置;可以看到,webpack-chain可以通过链式函数api来创建和修改webpack配置,从而更方便地创建和修改webpack配置。试想一下,如果一个webpack的配置需要在多个项目中使用,但是每个项目都有一些细微的不同配置,应该怎么处理呢?如果使用webpack-chain修改配置,用一个函数api就可以搞定,但是如果使用命令式编程,则需要逐步遍历整个webpack配置文件,找出需要修改的点,然后再修改可以对其进行修改,这无疑大大减轻了我们的工作量。函数式编程的特点根据维基百科的权威定义,函数式编程有以下特点:函数是一等公民。函数可以像变量一样赋值给其他变量,也可以作为参数,传入函数,或者作为其他变量使用。函数返回值。只使用表达式,而不是语句:表达式是一个简单的计算过程,它总是返回一个值。语句是执行一些动作,没有返回值。换句话说,函数式编程中的每一步都是一个简单的操作,并且有一个返回值。没有副作用不会产生除操作以外的其他结果。相同的输入总是得到相同的数据。不变性不修改变量,返回一个新值。引用透明函数的运行不依赖于外部变量,而只依赖于输入参数。以上特点是函数式编程的核心。基于这些特性,衍生出很多应用场景:纯函数:相同的输入得到相同的输出,无副作用。函数组合:将多个按顺序调用的函数组合成一个大函数,简化操作步骤。高阶函数:可以处理函数,接收一个或多个函数作为输入,并输出一个函数的函数。闭包:函数作用域嵌套,不同作用域变量共享。Currying:将一个多参数函数转换为多个嵌套的单参数函数。偏函数:缓存一些参数,使用的时候再让其他参数传入。Lazyevaluation:预定义多个操作,但不立即求值,只在需要值的时候求值,可以避免不必要的求值,提高性能。递归:一种控制函数调用循环的方法。尾递归:一种避免函数多层嵌套导致内存溢出的优化。链式调用:让代码更优雅。在我们的日常工作中存在大量这样的应用场景。接下来,我们来看几个案例。函数式编程的常见案例基于函数式编程的应用场景,我们来实现几个具体的案例。函数组合柯里化偏函数高阶函数尾递归链式调用1.函数组合,组合多个函数步骤。functioncompose(f,g){returnfunction(){returnf.call(this,g.apply(this,arguments));};}functiontoLocaleUpperCase(str){returnstr.toLocaleUpperCase();}functiontoSigh(str){returnstr+"!";}//将多个函数按执行顺序合并为一个函数,简化多个调用步骤。constcomposedFn=compose(toSigh,toLocaleUpperCase);console.log("函数组合:",composedFn("msx"));//函数组合:MSX!2、柯里化,将一个多参数函数转换成多个嵌套的单参数函数。//柯里化函数curry(targetfn){varnumOfArgs=targetfn.length;返回函数fn(...rest){if(rest.lengthc<10).Take(3)//只要不调用ToList,就不会求值最优解,会去价值。.ToList();上面代码中,传统求值会遍历2次,第一次遍历整个数组(8项),过滤掉小于10的项,输出[4,7,3,2],第二次遍历this数组(4项),输出[4,7,3]。如果使用惰性求值,所有预定义的操作都会一起判断,所以只需要遍历一次。遍历时判断是否小于10,小于10的个数是否为3,遍历到第5项时,可以输出[4,7,3]。相比于传统求值遍历的8+4=12项,惰性求值只需要遍历5项,程序运行效率自然提高。5、高阶函数,可以处理函数的函数(接收一个或多个函数作为输入,输出一个函数)。//在React组件中,一个组件被封装为一个默认背景色的新组件。//styled-components就是这个原理functionwithBackgroundRedColor(wrapedComponent){returnclassextendsComponent{render(){return(

)}}}6.递归和尾递归。//普通递归,一种控制函数循环调用的方法。functionfibonacci(n){if(n===0){返回0;}如果(n===1){返回1;}返回斐波那契(n-1)+斐波那契(n-2);}控制台。log("没有使用尾递归,导致栈溢出",fibonacci(100));//尾递归,避免函数多级嵌套导致的内存溢出优化。functionfibonacci2(n,result,preValue){if(n==0){返回结果;}returnfibonacci2(n-1,preValue,result+preValue);}//result=0,preValue=1console.log("使用尾递归,不会出现栈溢出",fibonacci2(100,0,1));6.链式调用//在lodash中,一个方法调用完成后,可以继续链式调用其他方法。varusers=[{user:"barney",age:36},{user:"fred",age:40},{user:"pebbles",age:1},];varyounest=_.chain(users).sortBy("age").map(function(o){returno.user+"is"+o.age;}).head().value();//=>'pebblesis1'thinkandsummary本文从编程范式出发,分析了函数式编程的定位,进一步扩展了函数式编程的概念。然后结合一些工作案例,实战一下函数式编程的应用场景。希望大家能够轻松理解函数。编程。最后,如果你对此有什么想法,欢迎留言评论!