当前位置: 首页 > Web前端 > HTML

函数式编程的概念

时间:2023-03-28 17:16:42 HTML

抽象了现实世界中的事物以及事物与程序世界之间的联系(抽象了计算过程)。个人理解,仅供参考。下面将以冰箱里的大象作为面向对象的例子:在代码中,我们对类和实例对象进行操作。冰箱被抽象为容器类,大象被抽象为对象类,容器具有存储属性,对象具有放置属性;容器类可以实例化为冰箱对象,对象类可以实例化为大象对象,可以操作冰箱的存储方法和大象的放置方法来完成操作。函数式编程:在代码中,我们操纵方法。把大象放进冰箱的过程整理成一组过程,也就是一组方法,我们不需要关心过程中发生了什么。只需要进入冰箱和大象,通过内部流程得到最终的结果。流程化:一步步操作,打开冰箱,把大象放进去,关上冰箱。//非函数式letnum1=2;letnum2=3;letsum=num1+num2;console.log(sum);//函数式add(n1,n2){returnn1+n2;}letsum=add(2,3);console.log(sum);基础知识高阶函数可以将函数作为参数传递给另一个函数,也可以将函数作为另一个函数的返回结果//filter高阶函数实现了Array.prototype。filterTest=function(fn){letresult=[];for(letindex=0;indexvalue>5));close封装的本质:函数在执行时会被放入一个执行栈。函数执行完毕后,将从执行栈中移除。但是堆上的作用域成员由于被外部引用而不能释放,所以内部函数仍然可以访问外部函数。成员函数once(fn){letdone=false;返回函数(){if(!done){done=true;返回fn.apply(this,arguments);}};}letpay=once((money)=>{console.log(`Paid${money}`);});pay(10);pay(10);pay(10);纯函数相同的输入总会得到相同的输出,lodash是一个纯函数库。优点因为纯函数对于相同的输入总是有相同的结果,所以可以缓存纯函数的结果纯函数使测试更容易(单元测试)并行处理const_=require("lodash");functiongetArea(r){returnMath.PI*r*r;}//memoize实现函数memoize(fn){letcache={};returnfunction(){letarg_str=JSON.stringify(arguments);缓存[arg_str]=缓存[arg_str]||fn.apply(fn,参数);returncache[arg_str];};}letgetAreaWithMemory=memoize(getArea);console.log(getAreaWithMemory(5));//让getAreaWithMemory=_.memoize(getArea);//console.log(getAreaWithMemory(4));副作用使函数不纯。纯函数基于相同的输入返回相同的输出。如果函数依赖于外部状态,则无法保证输出相同,会产生副作用。Currying当一个函数有多个参数时,先传递一些参数来调用它(这部分参数以后永远不会改变)。然后返回一个新的函数来接收剩下的参数并返回结果const_=require("lodash");functiongetSum(a,b,c){returna+b+c;}functioncurry(func){returnfunctioncurriedFn(...args){if(args.lengths.toUpperCase();//constreverse=(arr)=>arr.reverse();//constfirst=(arr)=>arr[0];//constf=_.flowRight(toUpper,first,reverse);//console.log(f(["one","two","three"]));functioncompose(...fns){返回函数(值){returnfns.reverse().reduce(function(acc,fn){returnfn(acc);},value);};}consttoUpper=(s)=>s.toUpperCase();constreverse=(arr)=>arr。撤销();constfirst=(arr)=>arr[0];constf=compose(toUpper,first,reverse);console.log(f(["一","二","三"]));仿函数是由普通对象实现的特殊容器,该对象具有运行函数处理值的map方法仿函数是实现地图契约的对象。map方法返回一个包含新值的仿函数。FunctorclassContainer{constructor(value){this._value=value;}map(fn){returnContainer.of(fn(this._value));}staticof(value){returnnewContainer(value);}}letresult=Container.of(5).map((x)=>x+1).map((x)=>x*x);console.log(result._value);可能处理外部空值到防止空值异常classMaybe{constructor(value){this._value=value;}map(fn){returnthis.isNull()?Maybe.of(null):Maybe.of(fn(this._value));}isNull(){返回this._value===null||this._value===undefined;}staticof(value){returnnewMaybe(value);}}//letresult=Maybe.of(null).map((x)=>x+1);//console.log(result);让result=Maybe.of(10).map((x)=>x+1);console.log(result._value);任一个都可以用于异常处理(value){this._value=value;}map(fn){returnRight.of(fn(this._value));}staticof(value){returnnewRight(value);}}functionparseJson(value){try{returnRight.of(JSON.parse(value));}catch(e){returnLeft.of({error:e.message});}}letresult=parseJson('{"key":"value"}').map((x)=>x.key.toUpperCase());console.log(result);IO内部封装的value是一个函数,将非纯操作封装到这个函数中,将非纯操作交给调用者处理constfp=require("lodash/fp");classIO{constructor(fn){这。_value=fn;}map(fn){returnnewIO(fp.flowRight(fn,this._value));}staticof(x){returnnewIO(()=>x);}}letpath=IO.of(process).map((p)=>p.execPath);console.log(path._value());Task异步执行folktale标准函数式编程库constfp=require("lodash/fp");constfs=require("fs");const{task}=require("folktale/concurrency/task");functionreadFile(filename){returntask((resolve)=>{fs.readFile(filename,"utf-8",(err,data)=>{if(err){resolve.reject(err);}resolve.resolve(data);});});}readFile("package.json").run().listen({onRejected:(err)=>{console.log(err);},onResolved:(data)=>{console.log(data);},});Monad(单子)通过join方法避免免函子套套constfs=require("fs");constfp=require("lodash/fp");classIO{constructor(fn){this._value=fn;}staticof(x){returnnewIO(()=>{returnx;});}map(fn){returnnewIO(fp.flowRight(fn,this._value));}join(){returnthis._value();}flatMap(fn){returnthis.map(fn).join();}}letreadFile=function(filename){returnnewIO(()=>{returnfs.readFileSync(filename,"utf-8");});};letprint=function(x){returnnewIO(()=>{console.log(x);returnx;});};letresult=readFile("package.json").flatMap(fp.toUpper).join();console.log(result);