纯函数与高阶函数 | 青训营笔记

280 阅读3分钟

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

在字节青训营的第三天,学习了 JavaScript 相关的内容,其中包含纯函数与高阶函数的内容,记录总结,分享出来。

纯函数

纯函数的定义

一个函数要满足以下两条定义,它才能是一个纯函数

  • 函数传入相同的参数结果不变
  • 函数执行过程中没有副作用

下面这个加法函数,就是个很标准的纯函数

function add(a, b) {
  return a + b
}

而下面这个计数函数,并不是一个纯函数,因为每次调用的结果并不一致

let num = 0
function count() {
  return ++num
}

下面这个设置颜色的函数,虽然每次执行产生的结果一致,但它依旧不是纯函数,因为在其中修改 DOM 元素的状态,产生了副作用

function setColor(el, color) {
  el.style.color = color
}

你觉得下面这个防抖函数是纯函数吗?

function debounce(fn, time) {
  let id
  return function (...arg) {
    clearTimeout(id)
    id = setTimeout(() => {
      fn.apply(this, arg)
    }, time)
  }
}

虽然函数功能有点复杂,但判断纯函数只看两点:

  • 每次以相同的参数调用这个函数,返回的都是一个防抖函数,结果不变
  • 这个函数只是创建了一个防抖函数,并没有产生任何的副作用

所以,它就是一个防抖函数

纯函数的好处

知道了什么是纯函数,接下来说纯函数有什么好处,主要体现在下面这三方面

  1. 纯函数不依赖外部环境,移植方便,引入都能用
  2. 只需要看函数就能知道其功能,代码易读,可维护性高
  3. 测试方便

关于测试方便这点,我们以加法函数和计数函数比较说明

如果想测试加法函数的功能,只需要传入参数,判断是否得到想要的结果就行

function add(a, b) {
  return a + b
}

// 测试代码
console.assert(add(1, 2) == 3)
console.assert(add(3, 4) == 7)

而如果要测试计数函数的话,就需要构建出特有的环境,才能进行测试。比如我们希望断言其输出为 3,就需要提前调用两次

let num = 0
function count() {
  return ++num
}

// 测试代码
count()
count()
let result = count()
console.assert(result == 3)

console.assert 表示断言输出,如果断言为 false,则将一个错误消息写入控制台。如果断言是 true,没有任何反应。详情见 MDN

高阶函数

高阶函数的定义

接着我们来聊高阶函数,先说定义,满足以下任意一条,它就是一个高阶函数

  • 参数可以接受一个函数
  • 返回值是一个函数

之前举例的防抖函数,他就是一个典型的高阶函数

而下面个就不是高阶函数,因为既不接受函数作为参数,而且返回值也是一个对象

function low() {
  const fun = () => {}
  return { fun }
}

高阶函数的作用

一般情况下,高阶函数可以看作是函数工厂,它们用于生产实现某一功能逻辑的函数,但并不去执行。所以基本上所有的高阶函数都是纯函数。

利用高阶函数将某些非纯函数封装扩展,可以实现逻辑的同时只产生纯函数

平时多使用高阶函数来实现需求,能提高代码的可维护性

结语

如果喜欢或有所帮助的话,希望能点赞关注,鼓励一下作者。

如果文章有不正确或存疑的地方,欢迎评论指出。