高阶函数应用 —— 柯里化与反柯里化

#高阶函数

高阶函数叫法:切片编程 AOP
高阶函数满足条件:
   1.一个函数的参数是函数。
   2.一个函数的返回值是一个函数。
只要满足以上两点的其中一点就属于高阶函数。它可以满足我们在一个函数原有的逻辑上增加一些功能。


	/*
      需求是想在调用say之前做一些逻辑
    */ 
    let say = (...arge) => {
      console.log('笑',...arge)
    };

    // 在Function原型上添加before方法 参数是个函数 返回也是个函数(高阶函数)
    Function.prototype.before = function (cb) {
      return (...arge) => {    // 使用箭头函数保证this可以拿到before的调用者  这里也就是say
        cb()
        this(...arge)
      }
    }

    // 调用say上的before 返回一个函数
    let newSay = say.before(function(){
      console.log('糖')
    })

    newSay('哈哈哈','嘻嘻嘻');
    

函数柯里化

函数柯里化是函数式编程的重要思想,也是高阶函数中一个重要的应用,其含义是给函数分步传递参数,每次传递部分参数,并返回一个更具体的函数接收剩下的参数,这中间可嵌套多层这样的接收部分参数的函数,直至返回最后结果。
也就数说把函数范围缩小,变的更具体。


	// 检查content是不是type类型
    function checkType (content,type) {
      return Object.prototype.toString.call(content) === `[object ${type}]`
    }

    // 一般情况下我们直接这样使用
    console.log(checkType('哈哈哈','String'))
    
    // 柯里化一下
    function checkType (type) {
      return function(content){
        return Object.prototype.toString.call(content) === `[object ${type}]`;
      }
    }

    let isString = checkType('String');
    
    console.log(isString('哈哈哈哈哈'));
    
柯里化通用式

我们接下来封装一个通用的柯里化转换函数,可以将任意函数转换成柯里化。


	// 累加函数
    const add = (a, b, c, d, e) => {
      return a + b + c + d + e
    }

    // 柯里化通用式
    let currying = (fn, ...arr) => {
      let len = fn.length;

      return (...arge) => {
        arr = [...arr, ...arge];

        if (arr.length < len) {
          return currying(fn, ...arr)
        };

        return fn(...arr)
      }
    }

    // 通过currying对add进行柯里化
    console.log(currying(add, 1, 2)(3)(4, 5))
    

用checkType方法结合柯里化通用式(currying )使用:


	// 柯里化通用式
    let currying = (fn, ...arr) => {
      let len = fn.length;

      return (...arge) => {
        arr = [...arr, ...arge];

        if (arr.length < len) {
          return currying(fn, ...arr)
        };

        return fn(...arr)
      }
    }

    // 检查content是不是type类型
    let checkType = (type,content) => {
      return Object.prototype.toString.call(content) === `[object ${type}]`
    }
    
    let isString = currying(checkType)('String');
    let isBoolean = currying(checkType,'Boolean');
    console.log(isString('hahhahahahah'));
    console.log(isBoolean(false));
    

反柯里化

反柯里化的思想与柯里化正好相反,如果说柯里化的过程是将函数拆分成功能更具体化的函数,那反柯里化的作用则在于扩大函数的适用性,使本来作为特定对象所拥有的功能函数可以被任意对象所使用。

反柯里化通用式

	// 反柯里化通用式
    let uncurring = (fn) => {
      return (...args) => {
        return fn.call(...args);
      }
    }
    

通过一个例子来感受一下反柯里化的应用。


	// 反柯里化通用式应用
	// 构造函数 F
	function F() {}
	
	// 拼接属性值的方法
	F.prototype.concatProps = function () {
	    let args = Array.from(arguments);
	    return args.reduce((prev, next) => `${this[prev]}&${this[next]}`);
	}
	
	// 使用 concatProps 的对象
	let obj = {
	    name: "杰克",
	    age: 16
	};
	
	// 使用反柯里化进行转化
	const concatProps = uncurring(F.prototype.concatProps);
	
	concatProps(obj, "name", "age");
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值