Rodrick

vuePress-theme-reco Rodrick    2022
Rodrick Rodrick

Choose mode

  • dark
  • auto
  • light
Home
Category
  • CS基础
  • 数据库
  • 前端
  • 其他
Tag
About
Timeline
D&T
  • 官方文档

    • Vue
    • Vue3
    • Webpack
    • MDN
    • Node中文网
    • React
    • 小程序
    • FineReport
  • 学习面试

    • 现代JavaScript教程
    • ES6
    • 阿西河
    • LeetCode
    • 牛客网
  • 工具

    • bejson
Contact
  • Github
  • Gitee
author-avatar

Rodrick

62

Article

18

Tag

Home
Category
  • CS基础
  • 数据库
  • 前端
  • 其他
Tag
About
Timeline
D&T
  • 官方文档

    • Vue
    • Vue3
    • Webpack
    • MDN
    • Node中文网
    • React
    • 小程序
    • FineReport
  • 学习面试

    • 现代JavaScript教程
    • ES6
    • 阿西河
    • LeetCode
    • 牛客网
  • 工具

    • bejson
Contact
  • Github
  • Gitee
  • JS

    • ES6核心语法
    • 模块化&Webpack
    • Promise&异步函数async
    • WebSocket原理浅析
    • axios的使用
    • ES5的变量提升和ES6的暂时性死区
    • call、apply、bind的用法
    • 对象的原始值转换
    • 可选链"?."
    • 随机数方法
    • 深浅拷贝实现
    • Array常用处理
    • 防抖与节流
    • postMessage窗口间通讯
    • 解构赋值
    • Map&Set
    • 日期和时间
    • 对象属性
    • Toast组件简单封装
    • 原型链
    • 类 Class
    • Generator与异步迭代
    • 偏函数Partial和柯里化Currying
    • DOM操作
    • 事件处理
    • 事件循环EventLoop
    • 网络请求
    • 浏览器中存储数据
    • 正则表达式
  • CSS

  • 其他

偏函数Partial和柯里化Currying

vuePress-theme-reco Rodrick    2022

偏函数Partial和柯里化Currying

Rodrick 2020-12-03 js

# 偏函数

我们知道 bind(this,arg1,arg2...) 可以绑定 this 且返回一个新的函数。
那么假设有如下的情况:

function mul(a, b) {
  return a * b
}

let doubleNum = mul.bind(null,2)

alert(doubleNum(2)) //4
alert(doubleNum(3)) //6
alert(doubleNum(4)) //8

在我们本有一个用于乘法的函数 mul(a,b) 的情况下,希望在它基础上生成一个能把参数直接翻倍(*2)的函数 doubleNum(x) 返回值为 x*2 ,那么用如上的方法实现,这样 doubleNum 就被称为一个偏函数。

维基百科  上对偏函数的定义:

翻译成中文:在计算机科学中,局部应用是指固定一个函数的一些参数,然后产生另一个更小元的函数。(什么是元?元是指函数参数的个数,比如一个带有两个参数的函数被称为二元函数。)


我自己的理解是:我们可以隐藏一部分调用者不必关心的参数信息,使得新的函数在减少元的情况下,产生一个新的、基于原函数功能的、特定用途的函数。

# 柯里化

柯里化(Currying) 是一种关于函数的高阶技术。它不仅被用于 JavaScript,还被用于其他编程语言。
柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)。
柯里化不会调用函数。它只是对函数进行转换。

# 实现柯里化

function curry(fn) {
  return function subCurry(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args)
    } else {
      return function (...args2) {
        return subCurry.apply(this, args.concat(args2))
      }
    }
  }
}

实现步骤:

  1. 先返回一个函数 subCurry ,如果这次调用 subCurry 的参数 ...args 的长度比原函数 fn 要求的参数要多或者相等,比如原函数 fn(a,b) ,然后这次调用 curry(fn)(a,b,c) ,那么就直接把参数给 fn 处理就好
  2. 如果给的参数少于 fn 指定的参数个数,那么我们再返回一个函数,你可以继续传参调用,调用的时候,新传入的 args2 和刚才传入的 args 合并后一起重新回调 subCurry ,直到参数总数满足 1. 里面提到的要求,然后返回最终的 fn.apply(this, 终极args)


使用:

function mul(a,b,c) {
  return a*b*c
}

let out = curry(mul)

alert(out(2,3,4))   // 24
alert(out(2)(3,4))	// 24
alert(out(2)(3)(4))	// 24

注意:  柯里化要求函数具有固定数量的参数。 使用 rest 参数的函数,例如 f(...args),不能以这种方式进行柯里化。

欢迎来到 Rodrick
看板娘