IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 如何使用纯函数包装器编写灵活的 JavaScript 代码 -> 正文阅读

[JavaScript知识库]如何使用纯函数包装器编写灵活的 JavaScript 代码

使用高阶函数 (HOF) 可以编写更具声明性、灵活性和紧凑性的代码。

软件开发的一项规则是不要接触任何工作正常的东西。如果您要增强已经存在的功能,您应该设计一个包装类。但请注意,创建这样的类会带来新问题,例如不灵活、副作用甚至约束。

您应该考虑编写适当的函数式包装函数以获得一个干净的包装函数,以获得更高的代码灵活性和更好的测试能力。

一些包装用例

包装一个函数意味着保持原始函数不变。已经给出的代码可能会影响其他对象,如果你改变它,你可能会产生连锁反应。— 您也可以说包装器是装饰器。

以下是一些用例:

  1. 向函数添加日志记录
  2. 从函数中获取时序信息
  3. 使用缓存(memoizing)来提高函数的性能

经典实现——记录器

您可能已经多次遇到过这个用例,是的,您可以使用断点来代替日志记录。但这是关于更深入的理解,因此您可以采用该技术。

如果不使用包装器,则必须修改函数的代码——进入和退出以产生一些日志输出。

这可能是您的原始代码:

更进一步而不换行意味着您必须添加一个auxiliaryVar来存储要记录和返回的值。

如果函数有多个return语句,请考虑开销。如果您只是即时计算返回表达式,则需要一个辅助变量来捕获该值。

所以一定有更好的方法,也有一种不容易发生意外和违反规则的技术:

如果它有效……不要碰它。

函数式实现——记录器

首先,您有一个确实实现了特定功能的函数,并且您想知道它的 I/O — 传入的参数和传出的参数。

编写一个具有单个参数的高阶函数——原始函数——并返回一个新函数,该函数将按顺序执行以下操作:

  1. 记录接收到的参数
  2. 调用原函数,捕获其返回值
  3. 记录该值
  4. 返回给调用者

实现这个过程,你会想出这个可能的代码作为解决方案:

by 返回的函数loggingWrap()具有以下特点:

  1. console.log()?显示原始函数的名称及其参数。
  2. fn()调用原始函数 (?),并存储返回值。
  3. 第二console.log()行显示函数名称及其返回值。
  4. fn()返回计算出的值。

提示:对于 Node 应用程序,您可能会采用更好的日志记录方式。可能使用Winston(通用记录器)、Morgan(适用于 http 记录)或Bunyan(专门用于 JSON 记录)。我的重点在于向您展示如何包装原始函数。使用这些库所需的更改很小,您将在本文末尾看到。

显示的方法适用于您的大多数功能。一个你可能已经想到的问题:

抛出异常的函数能否为这种明亮的包装技术带来黑暗?

异常

要检查这种情况,我们应该稍微增强您的日志记录功能。当您的原始函数抛出异常时,try/catch块是一个更好的主意。

无论您的包装函数是否抛出错误,此更改都会生成适当的日志记录语句。每次您都会收到一条消息,通知您一切正常或错误。除此之外,错误被重新抛出以进行处理。

提示:为了获得更好的日志输出,您可以添加日期和时间。增强参数的列出方式,等等。

尽管如此,这个实现仍然不完美。它有一个重要的缺陷。

创建一个纯包装器

提到纯函数意味着与没有副作用齐头并进。Console.log()就是这样的副作用。

使用像这样的固定语句会使您失去灵活性——您无法选择其他形式的日志记录——并使测试变得更加复杂。

你打算如何测试它?窥探console.log()方法?

这也不是很干净。了解特定函数的内部行为的依赖性对于测试它是必不可少的。事实并非如此。你想设计你的测试。你想要的是黑盒测试。

检查以下测试:

此测试将向您显示loggingWrap()确实按预期运行。第一个确实验证了日志记录被正确调用。第二个测试检查错误抛出以验证是否产生了正确的输出。因此,这是对工作代码段的有效解决方案。

虽然它没有解决缺乏灵活性的问题,但您应该将日志记录函数作为参数传递给包装函数。导致按需更改

如果您不传递任何内容,默认包装器将产生与loggingWrapCatcher.?但是您现在可以提供不同的日志记录系统。简单地将它存储到一个变量中并将它传递给包装函数。

像这样编写函数,我们可以利用存根。测试代码与之前几乎相同,但是由于您可以使用存根——stubby.logger()没有提供任何功能或副作用,因此它更安全。

在这种情况下,最初调用的真实函数console.log()不会造成任何伤害,但情况并非总是如此,因此建议使用存根。

新测试的工作方式与前一个相同,但使用并检查stubby.logger而不是处理原始console.log调用。这为您带来了更大的灵活性,因为您不再需要监视特定的硬编码函数 - 一种通用方法。

此外,它避免了由于副作用而导致的所有可能的问题,因此它更清洁,更安全。

结论

我想提一下,当你使用函数式技术时,永远记住,如果你让自己的工作复杂化,那么你一定是做错了。

函数loggingWrap()是不纯的,这应该让你敲响警钟。

您可能会争辩说,代码的简单性可能不足以决定它是否值得修复。您甚至可以在没有测试的情况下完成,并且您不需要能够更改日志生成的方式。但迟早,你会后悔做出这样的决定。

您应该始终尝试使用更清洁的解决方案。

因为通过添加包装类并使用您希望使用的任何记录器,这种方式为您带来了高度的灵活性 - 记录器代表您想要的任何所需更改。

此外,您现在已经完成了对任何所需实现的测试。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-13 09:11:00  更:2021-09-13 09:13:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 20:54:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码