浅析JS标识纯函数的作用及纯函数理解和为什么要构建纯函数

PS:vue3 的源码里大量使用了纯函数注释,那么我们就来了解下:使用 /*#__PURE__*/ 可标注纯函数,那么纯函数是什么,有什么作用?

1、纯函数(pure function)

(1)返回结果只依赖它的参数,传入的参数一样,返回的结果也是一样的

(2)执行时不改变作用域外的数据

(3)不产生副作用

2、优点:

(1)代码阅读性提高

(2)提高了代码的复用性

(3)IO简单,测试简单

(4)可作缓存或记忆功能

3、了解下什么是可观察的副作用?

一个可以被观察的副作用指的是在函数内部与其外部的任意交互。这个交互可能是在函数内修改外部的变量,或者在函数里调用另外一个函数等。

注: 如果纯函数调用纯函数,则不产生副作用,依旧是纯函数。

副作用来自,但不限于:

  • 进行一个 HTTP 请求
  • 输出数据到屏幕或者控制台(如 canvas 或 console.log )
  • DOM 查询/操作
  • Math.random()
  • 获取的当前时间

副作用本身并不是毒药,某些时候往往是必需的。 但是,就纯函数而言是不能包含任何副作用的。当然,并非所有函数都必须是纯函数。

纯函数是函数式编程里面非常重要的概念。简单来说,一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。这么说肯定比较抽象,我们把它掰开来看:

1、函数的返回结果只依赖于它的参数

  foo 函数不是一个纯函数,因为它返回的结果依赖于外部变量 a,我们在不知道 a 的值的情况下,并不能保证 foo(2) 的返回值是 3。

虽然 foo 函数的代码实现并没有变化,传入的参数也没有变化,但它的返回值却是不可预料的,现在 foo(2) 是 3,可能过了一会就是 4 了,因为 a 可能发生了变化变成了 2。

现在 foo 的返回结果只依赖于它的参数 xbfoo(1, 2) 永远是 3。今天是 3,明天也是 3,在服务器跑是 3,在客户端跑也 3,不管你外部发生了什么变化, foo(1, 2) 永远是 3。只要 foo 代码不改变,你传入的参数是确定的,那么 foo(1, 2) 的值永远是可预料的。

这就是纯函数的第一个条件:一个函数的返回结果只依赖于它的参数。

2、函数执行过程没有副作用

一个函数执行过程对产生了外部可观察的变化,那么就说这个函数是有副作用的。我们修改一下 foo

我们把原来的 x 换成了 obj,我现在可以往里面传一个对象进行计算,计算的过程里面并不会对传入的对象进行修改,计算前后的 counter 不会发生任何变化,计算前是 1,计算后也是 1,它现在是纯的。但是我再稍微修改一下它:

现在情况发生了变化,我在 foo 内部加了一句 obj.x = 2,计算前 counter.x 是 1,但是计算以后 counter.x 是 2。 foo 函数的执行对外部的 counter 产生了影响,它产生了副作用,因为它修改了外部传进来的对象,现在它是不纯的。

但是你在函数内部构建的变量,然后进行数据的修改不是副作用:

虽然 foo 函数内部修改了 obj,但是 obj 是内部变量,外部程序根本观察不到,修改 obj 并不会产生外部可观察的变化,这个函数是没有副作用的,因此它是一个纯函数。

除了修改外部的变量,一个函数在执行过程中还有很多方式产生外部可观察的变化,比如说调用 DOM API 修改页面,或者你发送了 Ajax 请求,还有调用 window.reload 刷新浏览器,甚至是 console.log 往控制台打印数据也是副作用。

纯函数很严格,也就是说你几乎除了计算数据以外什么都不能干,计算的时候还不能依赖除了函数参数以外的数据

3、总结:一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。

因为纯函数非常”靠谱”,执行一个纯函数你不用担心它会干什么坏事,它不会产生不可预料的行为,也不会对外部产生影响。不管何时何地,你给它什么它就会乖乖地吐出什么。如果你的应用程序大多数函数都是由纯函数组成,那么你的程序测试、调试起来会非常方便。

最后一个问题来了,那么我可以将所有函数都设为纯函数吗?

是的,从技术上讲,你可以。 但是只有纯函数的应用程序可能做不了多少。 您的应用程序会产生副作用,例如 HTTP 调用、IO 操作等等。 请在尽可能多的地方使用纯函数。 尽可能隔离不纯函数(副作用)。 它将大大提高程序的可读性、可调试性和可测试。

纯函数在函数式编程中被大量使用,而且诸如 ReactJS 和 Redux 等优质的库都要求使用纯函数。当然,纯函数也可以用在平常的JS开发中使用,不一定要限死在某个编程范式中。你可以自由地混合纯的和非纯的函数,这完全没问题。

事实上,并非所有函数都一定要是纯函数。 例如,操作 DOM 的按钮按下的事件处理程序就不适合纯函数。 不过,这种事件处理函数可以调用其他纯函数来处理,以此减少项目中不纯函数的数量。

另一个使用纯函数的原因是测试以及重构。

使用纯函数的一个主要好处是它们可以直接测。 如果传入相同的参数,它们将始终产生相同的结果,这对于测试的编写是非常友好的。

同时纯函数还使得维护和重构代码变得更加容易。你可以放心地重构一个纯函数,不必操心没注意到的副作用搞乱了整个应用而导致终调试地狱。

如果项目中充斥着副作用,那么函数/模块之间的逻辑可能互相交织耦合,在后期新增逻辑时可能由于依赖复杂而难以重构,更常见的是开发为了应付需求而不断的引入新的副作用到原本的逻辑上从而导致代码变得越来越糟糕。

正确地使用纯函数可以产生更加高质量的代码,并且也是一种更加干净的编码方式。

Original: https://www.cnblogs.com/goloving/p/16261983.html
Author: 古兰精
Title: 浅析JS标识纯函数的作用及纯函数理解和为什么要构建纯函数

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/547503/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Visual Studio 2022

    感谢您下载 Visual Studio – Visual Studio (microsoft.com) Original: https://www.cnblogs.co…

    技术杂谈 2023年5月31日
    0109
  • 响应式编程的实践

    响应式编程在前端开发以及Android开发中有颇多运用,然而它的非阻塞异步编程模型以及对消息流的处理模式也在后端得到越来越多的应用。除了Netflix的OSS中大量使用了响应式编程…

    技术杂谈 2023年5月31日
    089
  • [python]-分割结果可视化

    常常会遇到需要将分割的结果可视化的问题,这里采用修改dataset的方式,传入原图路径,最终保存的图片是在原图上叠加分割的结果,可以根据需要修改颜色。注意:这里的颜色三元组顺序是B…

    技术杂谈 2023年7月10日
    064
  • [学习笔记]Java异常处理

    程序运行时,可能会发生各种错误,一些错误是可以避免的,还有些错误是随机出现的且不可避免,一个健壮的程序必须能够处理这些错误; Java内置一套异常处理机制,使用异常来表示错误; 异…

    技术杂谈 2023年7月24日
    065
  • Elasticsearch5.0 安装问题集锦

    elasticsearch 5.0 安装过程中遇到了一些问题,通过查找资料几乎都解决掉了,这里简单记录一下 ,供以后查阅参考,也希望可以帮助遇到同样问题的你。 问题一:警告提示 […

    技术杂谈 2023年6月1日
    081
  • 草图?不管黑猫白猫,能快速、有效把你的设计理念讲清楚才行

    我在日常工作中,经常要参加一些技术活动,或被拉去参加一些需求会或运营会,时间比较分散。 上周在参加一个代码评审时,发现程序上该复用的没有复用,却写了两份逻辑几乎相同的代码。另外,还…

    技术杂谈 2023年7月11日
    068
  • Kylin配置Spark并构建Cube

    HDP版本:2.6.4.0Kylin版本:2.5.1机器:三台 CentOS-7,8G 内存Kylin 的计算引擎除了 MapReduce ,还有速度更快的 Spark ,本文就以…

    技术杂谈 2023年7月24日
    093
  • 网络设备配置-7、配置单臂路由实现跨vlan通信

    一、前言 同系列前几篇:网络设备配置–1、配置交换机enable、console、telnet密码网络设备配置–2、通过交换机划分vlan网络设备配置&#8…

    技术杂谈 2023年7月11日
    094
  • appium工作原理

    博客园 :当前访问的博文已被密码保护 请输入阅读密码: Original: https://www.cnblogs.com/111testing/p/15721262.htmlAu…

    技术杂谈 2023年5月31日
    096
  • Kubernetes 概念整理

    注:以下大部分内容来自网上摘录,以便后期查阅。 Kubernetes (通常称为 K8s) 是用于自动部署、扩展和管理容器化(containerized)应用程序的开源系统,是 G…

    技术杂谈 2023年6月1日
    098
  • 小兔的棋盘(hdu2067)

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm…

    技术杂谈 2023年5月31日
    079
  • AT&T汇编语言——工具及程序组成

    1. 开发工具 在汇编语言中,用到的工具主要用下面几个: 汇编器、连接器、调试器、编译器 由于我在这里的是AT&T 汇编语言。所以工具下也都是gnu 下的那些。 1.1 汇…

    技术杂谈 2023年5月30日
    0108
  • MacBook 对rar后缀的文件进行加压

    https://www.theunarchiver.com/ 在百度云盘中下载了rar的压缩文件,电脑自带的只能对.zip进行解压 经过一番搜索和比较,The unarchiver…

    技术杂谈 2023年5月31日
    0128
  • 异常

    spring框架中 获取bean时 1.NoUniqueBeanDefinitionException:没有一个唯一的bean被发现异常 原因:ioc中有多个类型匹配的bean 2…

    技术杂谈 2023年7月11日
    089
  • eslint 报错-Missing space before value for key ‘xxx’

    es-lint报错 原因:对象值前没有加空格 解决: 本文来自博客园,作者:King-DA,转载请注明原文链接:https://www.cnblogs.com/qingmuchua…

    技术杂谈 2023年6月1日
    084
  • Zookeeper的选举机制和同步机制超详细讲解,面试经常问到!

    前言 zookeeper相信大家都不陌生,很多分布式中间件都利用zk来提供分布式一致性协调的特性。dubbo官方推荐使用zk作为注册中心,zk也是hadoop和Hbase的重要组件…

    技术杂谈 2023年7月11日
    090
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球