【基础】函数柯里化概念+手写+优缺点+使用场景

柯里化是一种将接受多个参数的函数转化为接受单一参数的函数的技术,通过闭包实现参数复用。文章介绍了从简单到高级的手写柯里化实现,包括不确定参数个数的情况,并提到了lodash库中的curry方法。柯里化能简化调用,支持偏函数和延迟执行,但也可能带来额外的内存占用和效率问题。
摘要由CSDN通过智能技术生成

柯里化概念

利用闭包特点,实现参数复用,把多参数函数变成一系列单参数函数

实现方式

简单 手写柯里化

前提:确定函数参数个数;只允许柯里化方式调用

      //封装公用方法 传入函数
      function curry(f) {
        return function (a) {
          return function (b) {
            return f(a, b)
          }
        }
      }
      function sum(a, b) {
        return a + b
      }
      //单独使用 传入参数
      function currySum(a) {
        return function (b) {
          return a + b
        }
      }
      console.log(curry(sum)(1)(2)) //3
      console.log(currySum(1)(2)) //3
高级 手写柯里化

前提:不确定函数参数;可以正常调用也可以柯里化方式调用,也可以偏函数(pratial)方式调用
重点步骤:

  • apply改变this指向
  • 柯里化式方法调用:递归
       function curry(f) {
        return function curried(...args) {
          console.log(args)
          //f.length 形参格式
          //判断是正常调用 还是柯里化方式调用
          if (args.length >= f.length) {
            console.log(args)
            console.log(f)
            return f.apply(f, args)
          } else {
            return function (...args2) {
              return curried.apply(this, args.concat(args2))
            }
          }
        }
      }
      function sum(a, b) {
        return a + b
      }
      sum = curry(sum)
      //正常调用
      console.log(sum(1, 2)) //3
      //   //柯里化
      console.log(sum(1)(2)) //3
      //   //偏函数
      let sum1 = sum(1)
      console.log(sum1(2)) //3
lodash

前提:类高级手写柯里化

      function sum(a, b) {
        return a + b
      }
      sum = _.curry(sum)
      //正常调用
      console.log(sum(1, 2)) //3
      //柯里化
      console.log(sum(1)(2)) //3
      //偏函数
      let sum1 = sum(1)
      console.log(sum1(2)) //3

好处

  • 参数复用,可以减少传递部分不变参数
      //九九乘法表
      function haskell(a, b) {
        return a * b
      }
      sum = _.curry(haskell)
      //偏函数 第一个值固定
      let sum1 = sum(9)
      console.log(sum1(1)) //9
      console.log(sum1(2)) //18
  • 延迟执行(手写bind)
function win() {
        return this
      }
      Function.prototype.bindFn = function (thisA) {
        if (typeof this !== 'function') {
          throw new Error(this + 'is not function')
        }
        if (thisA === null || typeof thisA === 'undefined') {
          thisA = win()
        }
        thisA = new Object(thisA)
        thisA['_fn'] = this
        let a = [...arguments].slice(1)
        return function () {
          var res = thisA['_fn'](...a)
          delete thisA['_fn']
          return res
        }
      }
      //测试
      function print(a, b) {
        console.log(this, a, b)
      }
      print.bindFn(null, 1, 2)() //window 1 2

缺点

  • 函数嵌套多
  • 占内存,可能导致内存泄漏(闭包)
  • 效率差(递归)
  • 变量存取慢(arguments)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值