JS进阶8 -- 函数柯里化

JS进阶8 -- 函数柯里化

  • JS进阶8 -- 函数柯里化
    • 什么是函数柯里化
      • 需求
      • 核心步骤
      • 总结
    • 柯里化面试题-全局变量
      • 需求
      • 核心步骤
      • 总结
    • 柯里化面试题-使用闭包
      • 需求
      • 核心步骤
      • 总结
    • 柯里化实际应用-类型判断
      • 需求
      • 核心步骤
      • 总结
    • 柯里化实际应用-固定参数
      • 需求
      • 核心步骤
      • 总结

在 JS进阶7 – 手写Promise及其API中我们手写了Promise的核心功能、实例及静态方法,并跑通了Promise A+规范的872个单元测试!本文将继续重点跟大家介绍JS中的第8个重点内容 – 函数柯里化。废话不多说,一起来看看吧!

JS进阶8 – 函数柯里化

这一节咱们来学习函数柯里化,在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

这一节咱们会学习的有:

  1. 什么是函数柯里化
  2. 经典面试题
  3. 柯里化实际应用

柯里化 作为一种高阶技术, 可以提升函数的复用性和灵活性。

什么是函数柯里化

函数柯里化 (Currying) 是一种将多个参数的函数转换为单个参数函数的技术。
转换完毕之后的函数:只传递函数的一部分参数来调用,让它返回一个新的函数去处理剩下的参数。

需求

// 调整函数 sum
function sum(num1, num2) {
  return num1 + num2
}

// 改写为 可以实现如下效果
console.log(sum(1)(2))// 

核心步骤

  1. sum改为接收一个参数,返回一个新函数。
  2. 新函数内部将参数1参数2累加并返回。
function sum(num1) {
  return function (num2) {
    return num1 + num2
  }
}

总结

什么是函数柯里化

  1. 函数柯里化是一种将多个参数的函数转换为单个参数函数的技术。
  2. 转换完毕之后的函数只需要传递一部分参数进行调用,并且会返回一个新的函数去处理剩下的参数。

柯里化面试题-全局变量

柯里化在面试的时候一般以笔试题出现,比如

需求

function sum(a, b, c, d, e) {
  return a + b + c + d + e
}
// 改写函数sum实现:参数传递到5个即可实现累加
// sum(1)(2)(3)(4)(5)
// sum(1)(2,3)(4)(5)
// sum(1)(2,3,4)(5)
// sum(1)(2,3)(4,5)

核心步骤

  1. 接收不定长参数
  2. 存储已传递的参数
  3. 判断长度
    1. 满足5:累加
    2. 不满足:继续返回函数本身
let nums = []
function currySum(...args) {
  nums.push(...args)
  if (nums.length >= 5) {
    return nums.reduce((prev, curv) => prev + curv, 0)
  } else {
    return currySum
  }
}

总结

柯里化面试题-全局变量

  1. 定义数组保存参数
  2. 函数接收不定长参数
  3. 调用时将传入的参数,添加到数组中,并判断数组长度:
    1. 满足长度要求:累加并返回结果
    2. 未达到长度要求:继续返回函数本身

柯里化面试题-使用闭包

需求

  1. 使用闭包将上一节代码中的全局变量,保护起来
  2. 支持自定义累加的参数个数
function sumMaker(length){
    // 逻辑略
}
// 支持5个累加
const sum5 = sumMaker(5)
// 支持7个累加
const sum7 = sumMaker(7)
sum7(1,2,3)(4,5,6,7)

核心步骤

  1. 定义外层函数:
    1. 定义参数length
    2. 将全局变量迁移到函数内
  2. 定义内层函数:
    1. 参数长度判断,使用传入的参数length
    2. 直接复用上一节的逻辑,并返回
function sumMaker(length) {
  let nums = []
  function inner(...args) {
    nums.push(...args)
    if (nums.length >= length) {
      return nums.reduce((prev, curv) => prev + curv, 0)
    } else {
      return inner
    }
  }
  return inner
}

总结

柯里化面试题-使用闭包

  1. 定义函数,接收参数,用来确定参数个数
  2. 内部将上一节的逻辑拷贝进去
  3. 返回原函数
  4. 通过这样的调整,可以让我们自定义参数的个数,并且没有上一节的全局变量数组

柯里化实际应用-类型判断

通过参数复用,实现一个类型判断生成器函数

需求

  1. 将下列4个类型判断函数,改写为通过函数typeOfTest动态生成
// 有如下4个函数
function isUndefined(thing) {
  return typeof thing === 'undefined'
}
function isNumber(thing) {
  return typeof thing === 'number'
}
function isString(thing) {
  return typeof thing === 'string'
}
function isFunction(thing) {
  return typeof thing === 'function'
}

// 改为通过 typeOfTest 生成:
const typeOfTest =function(){
   // 参数 和 逻辑略

}
const isUndefined = typeOfTest('undefined')
const isNumber = typeOfTest('number')
const isString = typeOfTest('string')
const isFunction = typeOfTest('function')

// 可以通过 isUndefined,isNumber,isString,isFunction 来判断类型:

isUndefined(undefined) // true
isNumber('123') // false
isString('memeda') // true
isFunction(() => { }) // true

核心步骤

  1. typeOfTest接收参数type用来接收判断的类型
  2. 内部返回新函数,接收需要判断的值,并基于type进行判断
  3. 使用箭头函数改写为最简形式~~传送门-github
const typeOfTest = (type) => {
  return (thing) => {
    return typeof thing === type
  }
}

总结

柯里化实际应用-类型判断

  1. 定义函数,接收需要判断的类型名
  2. 内部返回一个新的函数,
    1. 新函数接收需要判断的具体的值
    2. 新函数内部根据外层函数传入的类型,以及传入的值进行判断并返回结果

柯里化实际应用-固定参数

依旧是一个参数复用的实际应用

需求

  1. 将如下3个请求的函数(都是post请求),变为通过axiosPost函数动态生成
  2. 实现函数axiosPost
 // 项目开发中不少请求的 请求方法 是相同的,比如
axios({
  url: 'url',
  method: 'get'
})
axios({
  url: 'url',
  method: 'get',
  params: {
    // 
  }
})
axios({
  url: 'url',
  method: 'post',
  data: ''
})
axios({
  url: 'url',
  method: 'post',
  data: '',
  headers: {

  }
})

// 固定请求参数,请求方法固定,其他参数从外部传递进来
// 需求: 实现方法requestWithMethod 支持如下调用
requestWithMethod('get')({
  url: '',
  params: {},
  headers: {}
})
requestWithMethod('post')({
  url: '',
  headers: {},
  data: {}
})

核心步骤

  1. 函数内部固定请求方法,post
  2. 函数内部调用axios发请求即可
  3. axios内部就是这样实现的
    1. 传送门-github:
function requestWithMethod(method) {
  return (config) => {
    return axios({
      method,
      ...config
    })
  }
}

总结

柯里化实际应用-固定参数

  1. 函数柯里化是一种函数式编程思想:将多个参数的函数转换为单个参数函数,调用时返回新的函数接收剩余参数
  2. 常见面试题,将函数改写为如下调用形式:核心思想就是返回新的函数,根据已经记录的参数长度判断:
    1. 长度符合要求:累加
    2. 长度不符合要求:继续返回
       function sum(a, b, c, d, e) {
         return a + b + c + d + e
       }
       // 改写函数sum实现:参数传递到5个即可实现累加
       // sum(1)(2)(3)(4)(5)
       // sum(1)(2,3)(4)(5)
       // sum(1)(2,3,4)(5)
       // sum(1)(2,3)(4,5)
    
  3. 常见应用:固定参数,比如axios中的:
    1. 类型判断函数
    2. get,post,put等别名方法
    3. 就用到了柯里化的思想

你可能感兴趣的:(JS进阶,javascript,ecmascript,前端,chrome)