传统的使用方法:

_.map([1,2,3], (row)=> row*2) //[2,4,6]

fp之后却可以这样用:

fp.map((row)=> row*2)([1,2,3]) //[2,4,6]

这种方式咋一看有些诡异,但如果是比较复杂的数据处理,就会体现出FP的好处:

之前:

var data = _.map([1,2,3], row => row*2).filter( row => row != 2) // [4,6]

之后

var mapMethod = fp.map( row => row * 2 );
var filterMethod = fp.filter( row => row != 2 );
var data = filterMethod(mapMethod([1,2,3])); // [4,6]

或者可以用flow进行组合包装:

var flowMethod = fp.flow( mapMethod, filterMethod );
var data = flowMethod([1,2,3]); //[4,6]

意味着,不应该需要关注具体调用的是哪个方法 ,而应该每个方法可以很轻易地组合与调整,只需要最后传入数据即可。因为对于代码消费者而言, _.map, filter这些方法是他不应该关心的,而如果想调整顺序,比如先filter再map,就会带来很多的麻烦,需要去修改源码。

lodash中的fp有何特性?

其核心特性就三个:自动curry化,迭代优先数据置后,immutable。

自动curry化(柯里化):可以参照 _.curry 的说明, 主要是可以转换函数调用方式, 很方便地生成新函数:

var abc = function(a,b,c){ return [a,b,c]; }
var curried = _.curry(abc);
curried(1)(2)(3) // -> [1,2,3]
curried(1,2)(3) // -> [1,2,3]
//而在fp中自动就有这个行为, 比如_.delay默认需要2个参数,则会能这样调用:
fp.delay(1500)(()=> console.log('delay'))

咦,调用方式有点奇怪,delay的文档里写的是_.delay(func, wait, [args]),为什么会先传入wait了?其实,这就是迭代优先数据置后的效果。

immutable这个有点费解,跟immutablejs似乎不是一回事,他解决的是传入的函数被修改的问题:

var mapMethod = (row)=> row*2;
var process = (data)=> _.map(data, mapMethod);
mapMethod = (row)=> row*3;
process([1,2,3]) // -> [3,6,9]; 传统方式下其调用的函数被修改了var mapMethod2 = (row)=> row*2;
var process2 = fp.map(mapMethod2);
mapMethod2 = (row)=> row*3;
process2([1,2,3]) // -> [2,4,6]; fp的方式下已经传入的函数不会被修改

与传统的比较

传统方式当然也有办法,那就是封装为类与对象。比如上面的处理,用类与对象的方式就可以这样:

class Dealer {constructor(val){ this.val = val; } map(){ this.val = _.map(this.val, row => row*2); return this; }filter(){ this.val = _.map(this.val, row => row !=2 ); return this; }value(){ return this.val; }
}
var dealer = new Dealer([1,2,3]);
var data = dealer.map().filter().value();

当然也不错,不过,代码多了好多呀,而且如果想扩展怎么办?需要用类的继承,或是原型继承。

class Dealer2 extends Dealer { ... } // 类的继承
Dealer1.prototype.newMethod = function(){}... //原型继承

但如果是fp的方式呢?直接再调用另一个函数就好了,至于函数从哪里来,没所谓。数据的处理变得非常地简单直接:输出一个数据,经过一系列函数的处理,输出另一个数据。

那么,fp是银弹么?能解决所有的问题?也不尽然。

fp用于数据处理的组合扩展方面非常强大,但如果涉及到状态管理,似乎就依然是类与对象会更加合适一些。

比如大名鼎鼎的redux,几乎全程fp,但却依然有至少一个对象: store 对象,里面有着4个方法: getState(), dispatch(action), subscribe(listener), replaceReducer(nextReducer)。

嗯, Dan Abramov其实还是很懂fp的短板的嘛。不过再看下redux中的createStore源码,其实还是满满的fp风格, 其对象创建大概是这样滴:

export default function createStore(...){var currentState = ...// more initialize codes...function getState(){ return currentState } function subscribe(listener) { ... }function dispatch(action) { ... }function replaceReducer(nextReducer) { ... }return {dispatch,subscribe,getState,replaceReducer}
}

详解Lodash中的fp实现相关推荐

  1. 详解OpenCV中的Lucas Kanade稀疏光流单应追踪器

    详解OpenCV中的Lucas Kanade稀疏光流单应追踪器 1. 效果图 2. 源码 参考 这篇博客将详细介绍OpenCV中的Lucas Kanade稀疏光流单应追踪器. 光流是由物体或相机的运动 ...

  2. python操作目录_详解python中的文件与目录操作

    详解python中的文件与目录操作 一 获得当前路径 1.代码1 >>>import os >>>print('Current directory is ',os. ...

  3. python3中unicode怎么写_详解python3中ascii与Unicode使用

    这篇文章主要为大家详解python3中ascii与Unicode使用的相关资料,需要的朋友可以参考下# Auther: Aaron Fan ''' ASCII:不支持中文,1个英文占1个字节 Unic ...

  4. foreach php,详解PHP中foreach的用法和实例

    本篇文章介绍了详解PHP中foreach的用法和实例,详细介绍了foreach的用法,感兴趣的小伙伴们可以参考一下. 在PHP中经常会用到foreach的使用,而要用到foreach,就必须用到数组. ...

  5. python open 打开是什么类型的文件-详解Python中open()函数指定文件打开方式的用法...

    文件打开方式 当我们用open()函数去打开文件的时候,有好几种打开的模式. 'r'->只读 'w'->只写,文件已存在则清空,不存在则创建. 'a'->追加,写到文件末尾 'b'- ...

  6. python中list[1啥意思_详解Python中list[::-1]的几种用法

    本文主要介绍了Python中list[::-1]的几种用法,分享给大家,具体如下: s = "abcde" list的[]中有三个参数,用冒号分割 list[param1:para ...

  7. java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题

    先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...

  8. pythonnamedtuple定义类型_详解Python中namedtuple的使用

    namedtuple是Python中存储数据类型,比较常见的数据类型还有有list和tuple数据类型.相比于list,tuple中的元素不可修改,在映射中可以当键使用. namedtuple: na ...

  9. python停止线程池_详解python中Threadpool线程池任务终止示例代码

    需求 加入我们需要处理一串个位数(0~9),奇数时需要循环打印它:偶数则等待对应时长并完成所有任务:0则是错误,但不需要终止任务,可以自定义一些处理. 关键点 定义func函数处理需求 callbac ...

最新文章

  1. libevent和libcurl实现http和https服务器 cJSON使用
  2. 人工智能不仅仅是智能生活,还有失业问题!
  3. sonar 质量配置 操作(质量规则)
  4. PWN-COMPETITION-GeekChallenge2021
  5. 基于matlab数字识别算法系统设计与实现(含源文件)
  6. 《Spring实战》系列之Bean的装配-Days01
  7. Rust性能分析-迭代器的enumerate方法是否会影响程序性能
  8. android dp sp px_规范|iOS与Android设计规范解析(一)
  9. js事件流 事件捕获 及时间冒泡详解
  10. java根据坐标轴_java 根据坐标截取图片实例代码
  11. openGauss社区成立QA SIG
  12. 微信网页授获取code
  13. win10双系统启动黑屏,开始菜单闪烁(可能需要引导修复)
  14. 【深度学习】Mask DINO四部曲—DETR潘多拉魔盒的正确打开方式
  15. 西工大机考(社会学概论)大作业网考
  16. 韦东山嵌入式第一期学习笔记DAY_4——8_3编写第1个程序点亮LED
  17. 密室鼻祖 深红色房间超详细攻略
  18. 获取log文件信息,并保存至Excel文件
  19. Ubuntu 安装k8s集群
  20. Pots (模拟倒水)

热门文章

  1. python爬虫-世界今日疫情爬虫
  2. import和export在浏览器中的使用方式
  3. MIT赵选贺再发《Nature Biomedical Engineering》​!
  4. java redis实现抢购_【抢购/秒杀】redis实现高并发下的抢购/秒杀功能
  5. python京东预约抢购_京东抢购脚本js教程
  6. matlab单个像素面积,我用MATLAB计算出了图像目标区域的像素点个数,请问知道了目标区域的像素点怎么计算目标区域的面积?...
  7. 数据库数字孪生技术获突破,Ganos两项研究成果入选VLDB
  8. MFC 加载gif动态图片的方法
  9. xampp 下载地址
  10. 【滴水逆向笔记】C语言结构体