淘宝|前端开发函数式编程入门( 三 )


;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(thisarguments)); let init_data = https://mparticle.uc.cn/api/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 = https://mparticle.uc.cn/api/useMemo(() =computeExpensiveValue(a b) [a b
); 小结 综上 , 我们希望大家能记住几点: 函数式编程的核心概念很简单 , 就是将函数存到变量里 , 用在参数里 , 用在返回值里 在编程时要时刻记住将无副作用与有副作用代码分开 函数式编程的原理虽然很简单 , 但是因为大家习惯了命令式编程 , 刚开始学习时会有诸多不习惯 , 用多了就好了 函数式编程背后有其数学基础 , 在学习时可以先不要管它 , 当成设计模式学习 。 等将来熟悉之后 , 还是建议去了解下背后的真正原理 作者|旭伦 原文链接:http://click.aliyun.com/m/1000298234/ 本文为阿里云原创内容 , 未经允许不得转载 。