B.KEN

© B.KEN | Powered by LOFTER
标签: 书评
1  
 

javascript函数式编程

     喜欢用现有的方案来解决问题,对新事物的抗拒应该是一种本能。业界最佳实践往往就这样成为懒惰的接口,在拒绝尝试的同时,也失去了发掘新事物的美好。

    为什么要了解函数式?

    每个语言都有自己的优势,JS对函数的友好程度正是它的一个优势。说起来JS也支持继承这一套,而且使用原型链来实现比传统的面向对象语言更为底层(也相对灵活)。面向对象的思维和函数式的思维并不冲突(而是互补的),在JS中也都能得到支持,为何要拒绝了解函数式呢。

    函数式的思维有什么好?

    一个面向对象的系统,会尝试把事物分类,找出他们的层级关系(继承),然后尝试枚举对象的所有行为。这样的模式将行为依附到对象上,但也就失去了对行为本身做抽象的机会,有的行为就是单纯的行为,难以归类,也难以分层。

    函数式的思想是以函数作为抽象的单元,通过组合简单的动作来构建复杂的动作。而只要遵循“协议”,动作就是纯粹的通用的动作。这样的思考方式对流程管理更为友好。

    函数式怎么做?

    我本来想尝试概括一下函数式是什么,但发现并没有那个水平,所以不如说下函数式是怎么做的

    使用高阶函数

    高阶函数有两层意思,一个是以函数作为参数输入,另一个是以函数作为返回值。比如sort函数接收一个比较函数而alway函数则返回一个返回固定值的函数。

    前者通过传入函数,将条件对外开放“使用函数,而不是值”这句话听起来比较偏激,但实际上函数能返回任何值,而值只能是值。更多条件的开放,带来更大的灵活性

    后者则可以用来产生函数,听起来有点工厂的味道,只不过返回的不是对象。通过配置得到函数允许我们拥有更高的抽象。

    用 组合函数 来 组合 函数

    用小的动作组合形成大的动作,是函数式构建的模式。但相比起用switch,嵌套等底层的方式。函数式的思维会更倾向于使用函数来完成组合的工作,比如管道形式,链式调用,promise等。避免修改低层次的具体代码,提供更灵活的组合形式。

    通过控制突变来降低复杂度

    如果一个函数结果只取决于他的参数,并且不改变外界的状态,那他就是一个纯函数。纯函数可以放心地相互组合。纯粹不依赖状态的逻辑当然是不可能的。但通过对突变的控制,能够降低相互影响,从而降低复杂度。

    对象协作

    函数式再怎么好,也不是解决所有问题的最优解,在状态控制等方面,对象的思维更为自然。通过mixin方式对对象的方法进行扩展。是的方法不再依附于对象,而是遵循约定。这样子就可以用方法来扩展增强对象,再在外面套上函数式的壳,一切就变得流畅起来。

    最后

    在OO横行的年代,函数式的思维显得小众又装逼。

    但我最讨厌的就是别人跟我讲JS面向对象,面向对象只有在项目规模足够大,足够复杂的时候,才凸显出分层,聚类的优势,不然只会丧失灵活性变得臃肿起来。(再说这些人一般只是把方法放进类里就觉得是面向对象了,呵呵)JS虽然代码规模越来越大,但离工程化还是有距离的,很多时候分层分好就足以解决问题,非要聚出几个类来不是有病吗

    对比面向对象擅长多态控制,函数式的优势在于流程控制,毕竟是以动作分解作为抽象的维度,许多思维方式值得借鉴。但要在平时项目里面严格实践函数式,追求函数纯度的话,如果队友不理解函数式,看到你那绕来绕去的函数调用,估计会想把你砍死在厕所里。

    面向对象不是所有问题的最优解(函数式也不是),一股脑套用某种编程范式其实是一种偷懒的表现。接触多些不同的思维方式对于平时对问题进行抽象帮助还是挺大的。

    函数式最终的目标是你像讲需求一样就把代码写了,靠近人类的自然语言,压根不用写注释。但要感受到函数式的优美,确实是要多花些时间理解,至少不要去抵触他。

    书挺薄的,但不熟悉函数式的思维看起来会比较费脑子。花了一些时间之后,我觉得还是值得的。


评论(1)