博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
函数式编程的几个概念
阅读量:6605 次
发布时间:2019-06-24

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

Function Programming

本篇文章是自己对于JavaScript函数式编程一书的读书笔记。利用underscore框架介绍函数式编程几个概念。

高阶函数

1. 将函数作为参数;复制代码
function repeatedly(times,value){ return _.map(_.range(times),()=>{ return value }) }
function repeatedly(times,fun){ return _.map(_.range(times),fun) } repeatedly(3,function(){ return Math.floor(Math.random()*10+1) })复制代码

repeatedly是函数式编程的一个典型思维,将值变成函数。

2. 返回其他函数的函数。复制代码

react和redux里面用了大量的返回其他函数的函数。包括高阶组件,applyMiddleware函数。 Thunk函数也是一个返回其他函数的函数。

var Thunk = function(fn){        return function(){            var args = Array.prototype.slice.call(arguments);            return function(callback){                args.push(callback);                return fn.apply.(this,args);            }        }    }    var readFileThunk = Thunk(fs.readFile);    readFileThunk(fileA)(callback);复制代码

由函数构建函数

  1. 函数式的精华(dispatch函数);
function existy(x) {        return x != null;    }    function doWhen(cond, action) {        if (tructhy(cond))            return action();        else            return undefined;    }    function invoker(NAME, METHOD) {        return function (target) {            if (!existy(target)) {                alert('Must provide a target');            }            var targetMethod = target[NAME];            var args = _.rest(arguments);            return doWhen(existy(targetMethod) && METHOD === targetMethod, function () {                return targetMethod.apply(target, args);            });        }    }    function dispatch() {        var funs = _.toArray(arguments);        var size = funs.length;        return function (target) {            var ret = undefined;            var args = _.rest(arguments);            for (var funIndex = 0; funIndex < size; funIndex++) {                var fun = funs[funIndex];                ret = fun.apply(fun,construct(target,args))                if(existy(ret)) return ret;            }                        if(existy(ret)) return ret;        }    }    var str = dispatch(invoker('toString',Array.prototype.toString),invoker('toString',String.prototype.toString));    console.log(str('a'));    console.log(str(_.range(10)));复制代码

dispatch将多个invoker组合在一起,形成多态函数,或根据不同的参数产生不同行为的参数。 2. 柯里化。 对于每个逻辑参数,柯里化函数会逐渐返回已配置好的函数,直到所有的参数用完。

function curry(fun){    return function(firstArg){        retun function(secondArg){            return fun(firstArg,secondArg);        }    }}复制代码
  1. 部分应用。 柯里化函数逐渐返回消耗参数的函数,直到所有的参数耗尽,然而部分应用函数是一个"部分执行",等待接收剩余的参数立即执行的参数。
function partApply(f, x) {  return function(y) {    return f(x, y);  }}复制代码
  1. 通过组合端至端的拼接函数。 一个理想化的函数式程序是向函数流水线的一端输送的一块数据,从另一端输出一个全新的数据块。 例如: !_isString(name);
  • _isString接收一个对象,并返回一个布尔值。
  • !接收一个布尔值,并返回一个布尔值。

_.compose函数从右往左执行。也就是说,最右边的函数的结果会被送入其左侧的函数,一个接一个。

function not(x){    return !x;}var isntString = _.compose(not,_isString);复制代码

纯度,不变性和更改政策。

  1. pure function
  • 其结果只能从它的参数的值来计算。
  • 不能依赖于能被外部操作改变的数据。
  • 不能改变外部状态。 javaScript会导致不纯的函数或方法如Date.now(),console.log(),this和全局变量。
  1. 数据的不可变性。(immutablejs);
function touchAndLog(touchFn) {  let data = { key: 'value' };  touchFn(data);  console.log(data.key); // 猜猜会打印什么?}复制代码

在不查看 touchFn 的代码的情况下,因为不确定它对 data 做了什么,你是不可能知道会打印什么(这不是废话吗)。但如果 data 是 Immutable 的呢,你可以很肯定的知道打印的是 value。

  1. 更改政策。 随便拿到一个对象并改变它,更好的策略是把对象放入容器中,并更改容器。

基于流的编程。

  1. 惰性链。
function LazyChain(obj){    this._calls = [];    this._target = obj; }LazyChain.prototype.invoke = function(methodName){    var args = _.rest(arguments);    this._calls.push(function(target){        var meth = target[methodName];        return meth.apply(target,args);    })    return this;}LazyChain.prototype.force = ()=>{    return _.reduce(this._calls,function(target,thunk){        return thunk(target);    },this._target)}new LazyChain([1,2,3]).invoke('sort').force();复制代码

转载于:https://juejin.im/post/5adf464d518825673c618fcb

你可能感兴趣的文章
保存图片到图库
查看>>
从相册读取本地保存的二维码并跳转h5链接
查看>>
深入浅出MongoDB应用实战开发视频教程
查看>>
淘宝开店很多人挣钱了为什么你却没挣钱?
查看>>
mysql配置文件my.cnf详解
查看>>
deepin15.4 thinkphp5 nginx 验证码不显示的问题
查看>>
rman备份发生的一点事情(sysaux表空间丢失)
查看>>
BGP邻居状态机
查看>>
Linux学习笔记:sed
查看>>
svn服务器
查看>>
memcached学习了解
查看>>
我的友情链接
查看>>
topdownCar 例子
查看>>
数据库(分库分表)中间件对比
查看>>
加工中心的坐标系怎么看
查看>>
Python练习题(二)
查看>>
el表达式
查看>>
一、创建虚拟机及安装Centos7
查看>>
×××检测系统(小程序)
查看>>
二、架构搭建说明
查看>>