博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
javascript函数式编程入门小结
阅读量:6860 次
发布时间:2019-06-26

本文共 2173 字,大约阅读时间需要 7 分钟。

前言

最近花了不少时间接触学习javascript的函数式的编程方式,而后为了加深理解,又去折腾haskell。

不同于人们比较熟悉的命令式编程,如面向对象编程(oop),函数式编程(fp)是一种更加抽象,更加‘数学’的编程方式。

当然,也是一种更加‘痛苦’的编程方式,尤其是刚接触时,总是难以摆脱的命令式的思维方式,大脑回路总是会迷路。
不过幸运的是,javascript天生具备了函数式编程的基本元素,所以学习的起点不会太低。

初接触

第一个实例,函数式编程是如何做一个番茄炒鸡蛋的。

伪代码,对比oop:

Class Chef{  cook(m1,m2){    return m1+m2  }}chef = new Cheffood = chef.cook('番茄','鸡蛋')food //番茄炒蛋。

fp的方式

getMaterial(m){  return function(){    return m  }}cook(getM1,getM2){  return getM1()+getM2()}food = cook(getMaterial('番茄'),getMaterial('鸡蛋'));food //番茄炒蛋

那么现在,站在内存(拟作:你)变化的角度上,这两者的区别之处。

oop

1.你面前出现了一个厨师2.你前面出现了番茄,鸡蛋3.厨师把番茄和鸡蛋炒在一起4.厨师把番茄炒蛋装在盘子上4.你获得了番茄炒蛋

fp

1.你拿一个空盘子,你决定弄点东西在上面2.你面前出现了一个传说中的厨具。 //没错!小当家同款厨具,只要丢材料进去,它就能弄出美味佳肴!3.你虽然没有材料,但幸运的是,你有两张藏宝图,分别标示了番茄和鸡蛋的位置。通过藏宝图,就能找到所需的材料。4.你把两张藏宝图扔到厨具里,告诉它,它得自己去找材料。 //传说中的厨具就是这么牛逼!5.厨具获得了番茄6.厨具获得了鸡蛋7.厨具终于炒了番茄和鸡蛋7.finally,你获得了番茄炒蛋

对比一下这个过程,可以发现:

oop方式总是是在告诉系统,第一步应该干什么(搞个厨师)然后干什么(弄到番茄和鸡蛋)、按部就班,最后你就能得到想要的值(番茄炒蛋)。

fp方式呢,恰恰相反,它是惰性的。只有你需要什么的时候,函数才会运算,才会返回数值,而不是一开始就存在的。

就好像学渣考90分,是因为在考试之前,他努力学习,到了90分。

这是结果。
而学霸考90分,只是因为考试的时候,做到90分时,懒癌发作,不想做题了。
这是过程。

fp的特性

这里列举了当前接触到fp中编程思想中的几个重要特性

1.不可变数据

2.函数是一等公民,即能作为参数,也可以是返回值
3.惰性求值

1.不可变数据

由于fp中都是函数,为了保证程序的可靠性,同样的参数,传入同一套的函数中,必须保证结果也是一样的。如:

let o = {name:'zhouyg'};r1 = fn1(fn2(fn3(o)))r2 = fn1(fn2(fn3(o)))r1 === r2 //true

在javascript中的由于Array和Object的类型都是引用传递的。如果在函数内部改变了改变了原始o的值,那么改变了原始o的值,那么必然导致r1和r2的结果不一样。导致程序不可靠,不可维护。

这是javascript的特性引起的,需要额外的手段补救。

每次传递Object和Array时候,都做一个拷贝,使用拷贝后的对象作为函数参数

或者使用某些数据结构工具,例如F家著名的

2.函数是一等公民

javascript天然满足,常见的各种回调。

3.惰性求值

顾名思义,只有在需要用到的才去计算。这里强行设定一种情景,如一个加法函数:

没有惰性求值

function add(n1,n2){  if(n1<5){    return n1  }else{    return n1+n2  }}result = add(add(1,2),add(3,4)) //相当于add(3,4)的计算是浪费的。result//3

惰性求值

function add(n1,n2){  return n1+n2;}function preAdd(n1,n2){  return function(){    return add(n1,n2)  }}function doAdd(fn1,fn2){  n = fn1()  if(n<5){    return n     //只需要运行fn1,得到一个计算结果即可。  }else{    return add(fn1,fn2())  }}result = doAdd(preAdd(1,2),preAdd(3,4))result//10

对比一下可知,在javascript中的惰性求值,相当于先把参数先缓存着,return一个真正执行的计算的函数,等到需要结果采去执行。

这样的好处在于比较节省计算,尤其有时候这个在函数是不一定需要这个参数的时候。

最后

这里只是简单的回溯最近学习的fp的相关内容。并不是为了比较fp方式和其它编程方式的优劣,而是希望能够站在另外的一个角度,活跃大脑的思维,开拓视野,以更丰富的姿势来解决问题,毕竟俗话说得好,姿势就是力量。

转载地址:http://exxyl.baihongyu.com/

你可能感兴趣的文章
隐藏当前Activity而不关闭
查看>>
Navicat Premium 12.0.18安装与激活(转)
查看>>
LLVM与Clang的一些事儿
查看>>
问题总结
查看>>
深度解析利用ES6进行Promise封装总结
查看>>
零基础的你还在纠结怎么学习Python编程吗?
查看>>
Flask在Windows环境下的部署
查看>>
力扣(LeetCode)56
查看>>
图片懒加载通俗易懂
查看>>
浅析vue2.0的diff算法
查看>>
协方差深入解读
查看>>
使用Node.js和WebHDFS REST API访问Hadoop HDFS数据
查看>>
聊聊flink Table的Over Windows
查看>>
基本排序算法
查看>>
Node常用命令备忘
查看>>
阿里云ECS上CentOS系统配置从入门到进门
查看>>
民航业智能升级,安防巨头‘大华’如何利用 AI 保障机场安全
查看>>
支持向量机分类实战
查看>>
java-基础-JNI本地栈
查看>>
中国人工智能学会通讯——增强学习是人工智能的未来 1.3 增强学习的核心技术...
查看>>