你需要了解 JavaScript 中的纯函数和非纯函数

115 阅读5分钟

什么是函数?

在 JavaScript 的海洋中,函数是创建复杂和交互式应用程序的基本构建块。

函数最常见的用途之一是映射,它们获取输入值并产生相应的输出值。这允许数据的转换和操作,这对于创建动态用户体验至关重要。


什么是纯函数?

纯函数是返回值仅由其参数决定而没有任何副作用的函数。比方说,如果您在应用程序中n多次调用具有相同参数的函数和相同的位置数,那么它将始终返回相同的值。n纯函数不修改任何外部状态,例如函数外部的变量或对象。它们只使用输入参数来执行计算并返回结果。

动图什么是纯函数

告诉你我的意思..

下面的函数接受两个数字,ab,作为输入参数并返回它们的总和。这个函数是一个纯函数,因为它总是对相同的输入产生相同的输出并且没有任何副作用。

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

纯函数


什么是不纯函数?

不纯函数是一种函数,给定相同的输入,可能在不同的时间产生不同的输出。这是因为不纯函数可能依赖于影响其行为和输出的外部因素,例如全局变量或其他函数的变化。

动图什么是不纯函数

下面的函数通过每次调用时将其值增加 1 来修改外部变量计数器。这意味着它有副作用并且不是一个纯函数。

let counter = 0;

function increment() {
  counter++;
  return counter;
}

不纯函数


为什么纯函数有用?

与不纯函数相比,纯函数有几个优点:

1) 可预测性
因为纯函数对于给定的输入总是产生相同的输出,所以它们是可预测的并且易于推理。它更易于测试和调试,并降低了代码中出现意外行为的可能性。

2) 可重用性
纯函数是模块化和自包含的,这意味着它们可以在代码库的不同部分重用而不会影响其他部分。这可以节省时间并减少您需要编写的代码量。

3) 并行化
因为纯函数不修改外部状态,所以它们可以并行执行而不用担心竞争条件或其他同步问题。这可以导致更快、更高效的代码。


如何在 JavaScript 中创建纯函数?

1) 只使用输入参数
纯函数应该只使用它们的输入参数来执行计算并返回结果。他们不应该修改任何外部状态或依赖外部变量。

2)避免副作用
纯函数不应该有任何副作用,比如修改外部变量或对象。它们应该只返回一个基于输入参数的值。

3)避免全局状态
纯函数应该避免使用全局状态,比如全局变量或对象。这会使您的代码更难预测且更难调试。

4) 返回一个值
纯函数应该总是根据输入参数返回一个值。他们不应该依赖外部变量或对象来产生他们的输出。


纯函数与不纯函数

JavaScript 中的纯函数与非纯函数


JavaScript 中的内置纯函数:

Math.abs(): 返回数字的绝对值。

Math.ceil(): 返回大于或等于给定数字的最小整数。

Math.floor(): 返回小于或等于给定数字的最大整数。

Math.max(): 返回一组数字中的最大值。

Math.min(): 返回一组数字中的最小值。

Math.round(): 返回最接近给定数字的整数。

Math.sqrt(): 返回给定数字的平方根。

parseInt(): 将字符串转换为整数。

parseFloat(): 将字符串转换为浮点数。

JSON.parse(): 将 JSON 字符串转换为 JavaScript 对象。

Array.prototype.concat(): 返回一个新数组,其中包含原始数组的元素以及作为参数传入的任何其他元素。

Array.prototype.slice(): 返回一个新数组,其中包含原始数组的一部分,由开始和结束索引指定。

Array.prototype.map(): 返回一个新数组,它是对原始数组的每个元素调用提供的函数的结果。

Array.prototype.filter(): 返回一个新数组,该数组仅包含满足提供的测试函数的原始数组的元素。

Array.prototype.reduce(): 返回单个值,该值是将提供的函数应用于数组的每个元素的结果。

String.prototype.toUpperCase(): 返回一个新字符串,其中包含所有大写字母的原始字符串。

String.prototype.toLowerCase(): 返回一个新字符串,其中包含所有小写字母的原始字符串。


JavaScript 中的内置不纯函数:

Math.random(): 返回 0 到 1 之间的随机数。此函数依赖于外部状态,即随机数生成器的当前状态,每次调用时其输出都会发生变化。

Date.now(): 返回当前时间戳,即自 . 以来经过的毫秒数January 1, 1970。此函数依赖于外部状态,即当前时间,每次调用时其输出都会发生变化。

console.log(): 将消息写入控制台。它不返回值,但它具有将信息记录到控制台的副作用。

setTimeout(): 在以毫秒为单位指定的指定延迟后执行函数。这个函数有一个副作用,就是安排一个函数在未来执行。

setInterval(): 以指定的时间间隔执行函数,时间间隔以毫秒为单位。这个函数有一个副作用,就是安排一个函数以固定的时间间隔重复执行。

document.write(): 将 HTML 内容写入文档。它不返回值,但具有修改文档的副作用。

Math.floor(Math.random() * (max - min + 1) + min): 返回给定范围内的随机整数。此函数依赖于外部状态,即随机数生成器的当前状态,每次调用时其输出都会发生变化。

Math.pow(): 返回一个数的给定幂的结果。虽然此函数在数学上是纯的,但它可能会导致浮点舍入错误,从而使其输出不纯。