加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

总结下函数式编程与命令行编程体感上的最大区别:

(2022-05-22 09:43:46)

总结下函数式编程与命令行编程体感上的最大区别:

 

 

  1. 函数是一等公式,我们应该熟悉变量中保存函数再对其进行调用
  2. 函数可以出现在返回值里,最重要的用法就是把输入是n(n>2)个参数的函数转换成n个1个参数的串联调用,这就是传说中的柯里化。这种减少了参数的新函数,我们称之为偏函数
  3. 函数可以用做函数的参数,这样的函数称为高阶函数

 

 

偏函数可以当作是更灵活的参数默认值。

 

 

比如我们有个结构叫spm,由spm_a和spm_b组成。但是一个模块中spm_a是固定的,大部分时候只需要指定spm_b就可以了,我们就可以写一个偏函数:

 

 


const getSpm = function(spm_a, spm_b){    return [spm_a, spm_b];}const getSpmb = function(spm_b){    return getSpm(1000, spm_b);}console.log(getSpmb(1007));

 

 

高阶函数我们在前面的map和flatMap里面已经用得很熟了。但是,其实高阶函数值得学习的设计模式还不少。

 

 

比如给大家出一个思考题,如何用函数式方法实现一个只执行一次有效的函数?

 

 

不要用全局变量啊,那不是函数式思维,我们要用闭包。

 

 

once是一个高阶函数,返回值是一个函数,如果done是false,则将done设为true,然后执行fn。done是在返回函数的同一层,所以会被闭包记忆获取到:

 

 


const once = (fn) => {    let done = false;    return function() {        return done ? undefined : ((done=true), fn.apply(this,arguments));    }}let init_data = once(    () => {        console.log("Initialize data");    });init_data();init_data();

 

 

我们可以看到,第二次调用init_data()没有发生任何事情。

 

 

递归与记忆

 

 

前面介绍了这么多,但是函数编程其实还蛮复杂的,比如说涉及到递归。

 

 

递归中最简单的就是阶乘了吧:

 

 


let factorial = (n) => {    if (n===0){        return 1;    }    return n*factorial(n-1);}console.log(factorial(10));

 

 

但是我们都知道,这样做效率很低,会重复计算好多次。应该采用动态规划的办法。

 

 

那么如何在函数式编程中使用动态规划,换句话说我们如何保存已经计算过的值?

 

 

想必经过上一节学习,大家肯定想到要用闭包,没错,我们可以封装一个叫memo的高阶函数来实现这个功能:

 

 


const memo = (fn) => {    const cache = {};    return (arg) => cache[arg] || (cache[arg] = fn(arg));}

 

 

逻辑很简单,返回值是lamdba表达式,它仍然支持闭包,所以我们在其同层定义一个cache,然后如果cache中的某项为空则计算并保存之,如果已经有了就直接使用。

 

 

这个高阶函数很好用,阶乘的逻辑不用改,只要放到memo中就好了:

 

 


let fastFact = memo(    (n) => {        if (n<=0){            return 1;        }else{            return n * fastFact(n-1);        }    });

 

 

在本文即将结尾的时候,我们再回归到前端,React Hooks里面提供的useMemo,就是这样的记忆机制:

 

 


const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

 

 

小结

 

 

综上,我们希望大家能记住几点:

 

 

  1. 函数式编程的核心概念很简单,就是将函数存到变量里,用在参数里,用在返回值里
  2. 在编程时要时刻记住将无副作用与有副作用代码分开
  3. 函数式编程的原理虽然很简单,但是因为大家习惯了命令式编程,刚开始学习时会有诸多不习惯,用多了就好了
  4. 函数式编程背后有其数学基础,在学习时可以先不要管它,当成设计模式学习。等将来熟悉之后,还是建议去了解下背后的真正原理

0

阅读 收藏 喜欢 打印举报/Report
后一篇:Keil
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有