javascript函数式编程入门小结

媒介

近来花了不少时刻打仗进修javascript的函数式的编程体式格局,然后为了加深明白,又去折腾haskell。

不同于人们比较熟习的敕令式编程,如面向对象编程(oop),函数式编程(fp)是一种越发笼统,越发‘数学’的编程体式格局。
固然,也是一种越发‘痛楚’的编程体式格局,特别是刚打仗时,老是难以挣脱的敕令式的头脑体式格局,大脑回路老是会迷路。
不过荣幸的是,javascript生成具有了函数式编程的基础元素,所以进修的出发点不会太低。

初打仗

第一个实例,函数式编程是怎样做一个番茄炒鸡蛋的。
伪代码,对照oop:

Class Chef{
  cook(m1,m2){
    return m1+m2
  }
}
chef = new Chef
food = 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家有名的immutable.js

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体式格局和别的编程体式格局的好坏,而是愿望可以站在别的的一个角度,活泼大脑的头脑,开辟视野,以更雄厚的姿态来解决问题,毕竟俗话说得好,姿态就是气力。

    原文作者:zhouyg
    原文地址: https://segmentfault.com/a/1190000003741941
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞