js - 理解函数组合

Posted 耳东蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js - 理解函数组合相关的知识,希望对你有一定的参考价值。

怎么理解函数组合

compose(f, g, t) => x => f(g(t(x))

函数组合,字面意思将多个函数有序组合起来。有序组合的原因是不同的顺序返回的函数是不同函数。

var  compose  = require('ramda')

const f = x => x + 1;

const g = x => x * 2;

const fg1 = compose(f, g);

const fg2 = compose(g, f);

console.log(fg1(4)) // 9
console.log(fg2(4)) // 10


解释一下,函数组合执行的顺序是从右向左

fg1:(4 * 2) + 1 = 9
fg2:(4 + 1) * 2 = 10


上面的ES5代码执行

var compose = function(f,g) 
  return function(x) 
    return f(g(x));
  ;
;


当然这种写法不完善,因为只支持两个函数的输入。



手写函数组合

分解

  1. 返回高捷函数
  2. 高阶函数可以从右往左依次执行方法,并且将上一个方法的返回值传入到下一个方法中。


这个依次执行的方式可以想到的reduce和reduceRight方法,reduce方法就是将前一次循环得到的结果当成下次循环执行的参数。

手写版本

var compose = function() 
	const funcArray = [...arguments];
  
  return function () 
  	return funcArray.reduceRight(
      (arg, fn) => 
        return fn.apply(null, [].concat(arg)) // 这里使用这个是因为第一个执行的函数可能存在两个参数(最右边的函数)
      , 
      [...arguments]
    )
  


高颜值版本

var compose = (...fns) => (...args) => fns.reduceRight((arg, fn) => fn.apply(null, [].concat(arg)), args)


underscore 的 compose 函数

function compose() 
    var args = arguments;
    var start = args.length - 1;
    return function() 
        var i = start;
        var result = args[start].apply(this, arguments);
        while (i--) result = args[i].call(this, result);
        return result;
    ;
;


redux 中 compose

function compose(...funcs) 
  if (funcs.length === 0) 
    return arg => arg
  

  if (funcs.length === 1) 
    return funcs[0]
  

  return funcs.reduce((a, b) => (...args) => a(b(...args)))

理解一下:

function compose(...funcs) 
  if (funcs.length === 0) 
    return arg => arg
  

  if (funcs.length === 1) 
    return funcs[0]
  

  return funcs.reduce((a, b) => 
    return (...args) => 
        return a(b(...args))
        
    )



const f = x => x + 1;

const g = x => x * 2;

const h = x => x + 3;

let fg1 = compose(f, g, h);
let g2 = compose(h, g, f);

console.log(fg1(4)) 
console.log(fg2(4))

函数组合执行是从右向左的,reduce则是从左向右形成高阶函数。

let fg1 = compose(f, g, h);

return function(arg) 
	return f(g(h(arg)))


Ramda中的pipe【从左到右的组合】

var  compose, pipe  = require('ramda')

const f = x => x + 1;

const g = x => x * 2;

const fg1 = compose(f, g);

const fg2 = pipe(g, f);

console.log(fg1(4)) // 9
console.log(fg2(4)) // 9


应用

react高阶函数使用

withRoute(observer(inject('Store')(Index)))

const enhance = compose(withRoute, observer, inject('Store'));

enhance(Index);

参照

  • https://github.com/mqyqingfeng/Blog/issues/42
  • https://juejin.cn/post/6844903936378273799#heading-14

以上是关于js - 理解函数组合的主要内容,如果未能解决你的问题,请参考以下文章

深入理解js构造函数

深入理解js构造函数

深入理解JavaScript中创建对象模式的演变(原型)

深入理解JavaScript中创建对象模式的演变(原型)

js回调函数的简单理解

深入理解JavaScript中创建对象模式的演变(原型)