JavaScript学习与函数柯里化 | 青训营笔记

84 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的的第2天

各司其职

JavaScriptBehavioral
CSSPresentational
HTMLStrictural
  • html、css、js各司其职:结构、表现、行为分离
  • 应当避免不必要的由JS直接操作样式
  • 可以用class来表示状态
  • 纯展示类交互寻求零JS方案

组件封装

组件是指Web页面上抽出来一个个包含模版HTML、功能JS和样式CSS的单元。

  • 组件设计的原则: 封装性、正确性、扩展性、复用性
  • 实现组件的步骤
    • 结构设计
    • 展现效果
    • 行为设计
      • API(功能)
      • Eventr(控制流)
  • 三次重构
    • 插件化
    • 模版化
    • 抽象化(组件框架)

过程抽象

react hooks

  • 用来处理局部细节控制的一些方法
  • 函数式编程思想的基础应用

高阶函数

  1. HOF
  • 以函数为参数
  • 以函数为返回值
  • 常用于作为函数装饰器

例: Once、Throttle、Debounce、Consumer/2、Iterative

  1. 为什么要是用高阶函数
  • 纯函数(思考:高阶函数与纯函数的关系)
    • 测试方便,不需要考虑副作用
  • 编程范式:命令式与声明式
    • 命令式趋向于怎么做
    • 声明式趋向于做什么

函数的柯里化

柯里化(Currying)是一种关于函数的高阶技术。

固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数。核心思想是把多参数传入的函数拆成单参数(或部分)函数,内部再返回调用下一个单参数(或部分)函数,依次处理剩余的参数。

将型如f(a,b,c,d)的函数转换为f(a)(b)(c)(d)

  1. 比如我们需要实现类型判断的封装,我们可以使用Object.prototype.toString.call(obj)是否等于对应类型的输出值来实现第一个版本
const isArray = (value)=>{
  return Object.prototype.toString.call(value) == `[object Array]`
}
const isNumber = (value)=>{
  return Object.prototype.toString.call(value) == `[object Number]`
}
const isString = (value)=>{
  return Object.prototype.toString.call(value) == `[object String]`
}
const isBoolean = (value)=>{
  return Object.prototype.toString.call(value) == `[object Boolean]`
}

2. 接下来可以进一步封装一个高阶函数

const isType = (type, value)=>{
  return Object.prototype.toString.call(value) == `[object ${type}]`
}
  1. 柯里化

对于类型判断的方法,我们暂时封装到这里,接来下我们看如何实现上面的函数柯里化,即将型如f(a,b,c,d)的函数转换为f(a)(b)(c)(d),我们用sum方法来举例

// sum方法
const sum = (a,b,c,d)=>a+b+c+d
sum(1,2,3,4) // output: 10

分析:我们需要实现一个currying()函数,使得currying(sum)(1)(2)(3)(4)==10

//1. currying必须通过闭包实现变量私有化,并保存后续接收的变量到一个数组中,否则它就无法在接收到第四个参数是返回sum值
//2. currying的返回值为一个函数
//3. currying返回的函数在被调用完成后要么返回结果、要么还是返回一个函数
const currying = (fn)=>{
    let arr = []   //满足1
    let inner = (...args)=>{
      arr.push(...args)    //满足1
      //console.log(arr)     //调试
      return arr.length >= fn.length ? fn(...arr) : inner    //满足3
    }
    return inner//满足2
}

4. 应用柯里化

我们在上一步实现了对柯里化的一个封装,现在我们可以直接将这个currying函数应用于前面的类型判断函数