2020 年教会我的 10 件事

2025-06-07

2020 年教会我的 10 件事

2020年对我们很多人来说都是艰难的一年。我们大多数人搬出了办公室,住进了沙发、厨房、壁橱或其他临时办公区。虽然你可能错过了一些在车里度过的宝贵时光,或者错过了上下班路上无缘无故打喷嚏的尴尬时刻,但我们大多数人却获得了更重要的东西:时间

我尽力利用这段时间。无论是练习钢琴倒立,还是额外锻炼一小时,或是浏览任何我觉得合我口味的博客和文章。

我还专门抽出一些时间记录白天学到的东西。每当我发现新东西、学到新东西,或者在我认为与我的专业领域相关的领域获得新的见解或知识时,我都会记录下来。有机会的时候,我会亲自尝试,详细记录我的发现并与大家分享。

这可以是任何事情,从找到一段新的有用代码片段,到深入了解一个全新的概念或范式。今天,我想和大家分享一些我最喜欢的,希望你们能从中受益,并受到启发,走上这条属于自己的道路。

这篇文章我主要关注JavaScript。我也学过其他东西,但我觉得核心读者不会觉得我对乐高、钢琴或业余家具制作的渴望有什么意义。话虽如此,这篇文章开始感觉像是那种描述汤和拿破仑曾祖父关系的菜谱介绍。就给我汤?

汤,嗨!闲话少叙,以下是我在2020年学到的一些节选,以及我最喜欢的东西,按学习顺序排列。

1. Array.sort() 在不同的浏览器中表现不同

这更像是一个错误,我在今年春天早些时候为此苦苦思索了很久。请考虑以下几点:

在对数组进行排序时,我,可能还有很多其他人,都陷入了使用这个简单回调的陷阱:sort((x,y) => x < y))

然而,在一个简单的示例上运行它时,我们分别在 Chrome 和 Firefox 中得到以下内容:

数组排序1

接受的比较回调sort()必须返回10-1。因为我们的回调不返回任何值,而是返回布尔值。不同浏览器的 JavaScript 实现似乎在解释这些布尔值方面各有不同。

因此,尽管 Firefox 似乎接受(或者更确切地说将)布尔值分别解释为1-1,但不能保证其他浏览器也会做同样的事情,甚至不能保证 Firefox 本身将来会继续这样做。

Joakim 没有仔细阅读数组文档。别学 Joakim。好好读文档吧。

Chrome 也曾经根据数组的大小实现不同的排序算法,尽管后来已改为始终使用稳定的排序算法。

了解有关 .sort() 的更多信息

2. JSON.stringifys 可选的替换器参数。

每个涉足过 Web 开发的人,包括他们的母亲,都曾经,或者将来会在某个时候使用过JSON.stringify。但今年我突然意识到了这个函数的第二个参数:replacer。它可以在解析 JSON 时用作键值对的白名单。

json_stringify_1

但是 replacer 也可以是一个函数,可以用来验证、替换或解析(或任何其他功能。发挥创造力吧,各位女士们先生们)JSON 键值对。

json_stringify_2

这会对性能造成轻微的影响,正如您在这些基准测试中亲眼所见,但对于一般用例来说,这应该不会造成显著的差异。

阅读有关 JSON.stringify() 的更多信息

3. Array.filter() 不适用于 Promises

我倾向于大量使用数组方法。一个非常常见的模式是:执行一系列异步操作,然后迭代这些操作来处理数据并过滤掉不需要的内容。

我第一次遇到这个问题是在夏天,当时我的项目里,我们使用了一个函数来检查用户在执行某些操作时的访问级别。我们把它叫做userCan。通过让这个函数返回 true 或 false,它可以无缝地用作filter回调函数,以确定用户是否拥有执行任何给定操作的相关权限。

过滤器_1

假设actions用户发起了一批请求。我们需要确保只有用户有权执行的操作才会被执行。代码简化了,但你明白要点:

过滤器_3

简短而甜蜜。但是当我们引入异步操作时会发生什么userCan

过滤器_4

突然间所有用户操作都被允许了!用户不应该拥有这样的权限DROP_DATABASE。为什么会发生这种情况?

嗯,不幸的是Array.filter(),这是一个同步函数,因此不支持 Promise。因此,它filter()不会等待userCan解析值,而是直接接受 Promise 作为真值。

为了解决这个问题,我们需要发挥一些创造力。有几种方法可以解决这个问题,最常见的,也是我推荐的,是.map()与 结合使用.filter()

过滤器_5

我们在这里所做的是使用异步支持.map()来检查给定的谓词,并且当所有 Promises 都已解决时,从结果数组中过滤掉虚假值。

您也可以使用 来执行此操作.reduce(),但我发现它有点复杂。

过滤器_6

很整洁,不是吗?

了解有关 .filter() 的更多信息

4. 空值合并 vs. 逻辑或运算符

很多人,包括我自己,可能对编写类似下面的内容感到非常熟悉,以便在出现以下情况时有一个后备baz方案undefined

const foo = baz || "fallback"
Enter fullscreen mode Exit fullscreen mode

||检查诸如falsenull和 之类的虚假值0。但在某些情况下,您可能需要将其视为0实际值,或者更明确地处理空值。

无效

空值合并与不同之处在于,||当其左侧值为null或 时,它仅返回其右侧操作数undefined

空值合并在 TypeScript 3.7 版中引入,目前所有主流浏览器和Node.js 14的最新版本均支持该功能。

更多关于空值合并的信息请点击此处

5. 控制台.table()

今年夏天我第一次遇到它时,简直惊呆了。我们都是经验丰富的开发人员,所以我们console.log尽可能频繁地使用它,因为它可能是目前最强大的调试工具!好吧,我来告诉你,它console.table()确实存在,而且它有多棒:

控制台表

无论何时处理长数组对象,这都可以成为救星。

有关 console.table() 的更多信息,请参见此处

6. Promise 构造函数反模式

Promise 构造函数反模式,或者说是延迟反模式,指的是无缘无故地创建新对象,或者在本例中是无缘无故地创建新的 Promise。当我刚开始以初级开发人员的身份深入研究 Promise 时,我对此感到非常内疚。

它使代码变得复杂,并阻止拒绝和错误的正确传播。

我之前并不知道这是一种公认​​的反模式,我自己也自然而然地戒掉了这个习惯,直到今年我对此有了更多的了解。当你刚接触 Promise 时,很容易陷入这种工作方式,你可能不知道执行异步操作已经返回了一个 Promise,而你可以将其串联起来。

承诺_1

我们建议不要显式地创建一个新的 Promise,而是直接使用我们首先调用的异步函数返回的原始 Promise:

承诺_3

看起来不是漂亮多了?

在此处阅读有关 Promise 构造函数反模式的更多信息

7. 捕获等待的错误

现在来点更简单的。我们都知道,使用then和 来处理已解决和已拒绝的 Promise。但是,如果你想使用async/awaitcatch捕获错误,据我所知,你需要将其包装在try/catch块中,如下所示:

捕获1

但让我感到有趣和惊讶的是,我最近发现你实际上可以使用.catch()等待的承诺。

捕获_2

当然,当你思考这一点时,这很有意义,因为 async/await 实际上只是 Promises 之上的语法糖。

话虽如此,有人可能会提出应该坚持其中一种惯例的观点。虽然我通常同意这种观点,但在某些情况下,我发现它确实很方便。你怎么看?

8. 使用可选链进行函数调用。

这可能是常识,作为严格使用可选链的人,我想知道为什么我从来没有想到尝试这一点;您可以使用可选链进行函数调用?

可选_1

它很漂亮。。并且在使用 React 组件时经常会派上用场,例如,这些组件可能有也可能没有事件处理程序,例如onClick。不再有onClick={onClick && () => onClick(param)}

在此处了解有关可选链接的更多信息

9. 利用 Web Workers

JavaScript 运行时是单线程环境,这意味着程序中的代码无法并行执行,这与 Java 和 C# 等语言不同。这意味着 JavaScript 的代码执行本质上是阻塞的。我们必须等待一段代码执行完成,才能继续执行下一段代码。

不要与 Promises 或Node.js 的子进程混淆,Web Worker是将这种多线程行为引入 JavaScript 的一种方式。它们可以用于多种用途,但最常用的可能是将 CPU 密集型任务委托给其他线程,以防止长时间中断和用户界面阻塞。

与事件监听器和类似Socket.io,工作者使用消息系统相互通信,并且启动和运行非常简单。

worker_1

为了让工作者监听并响应主线程发送的消息,我们只需要定义onmessage处理程序就可以了。

worker_2

我们现在需要做的就是确保我们的主线程有某种方法来处理我们的工作者发回的消息。

worker_3

虽然 Web Workers 非常有用,但它们也有一些限制,例如无法访问 DOM。

点击此处了解有关 Web Workers 的更多信息

10. 不依赖依赖项

最后,但同样重要的一点是,我想将这个荣誉位置授予今年可能教会我最多的事情。

去年春季早些时候,Deno发布了 1.0 版本,其中包含一系列引人入胜的功能。Deno 是由 Node.js 创始人Ryan Dahl (ry)开发的全新、安全的 JavaScript 和 TypeScript 运行时。

我不会在这里深入探讨 Deno,但如果您想了解更多信息,这里有一个链接。

作为一名狂热的 Node.js 工程师,我抓住机会去探索它的功能。我花了一个周末的时间尝试编写一个文件和 Web 服务器,它的功能如下:

  • 具有实时重新加载功能

  • 支持客户端路由

  • 需要零配置..

……同时完全无依赖。这意味着无需使用任何第三方软件包。最终的项目名为Denoliver,我于 2020 年晚些时候发布了 2.0 版本。

我从这个实验中学到了很多东西(绝对不是脏话!)。解决那些通常用 解决的问题,真的非常有趣npm install solution

我强烈推荐这种方法。这真是一段奇妙的旅程。如果你想亲自体验一下这个项目,寻找灵感,或者想贡献一份力量,可以在这里找到。

GitHub 徽标 乔基蒙格/德诺利弗

一个简单的、无依赖的 Deno 静态文件服务器,可能是有史以来最糟糕的名字。

这是肝脏


Denoliver是一个小型、零配置的开发和静态文件服务器,具有实时重新加载功能,用 TypeScript 为 Deno 编写,旨在用于原型设计和单页应用程序。

先决条件

要运行它,您需要安装Deno 1.0 或更高版本。

主要特点

  • 无依赖!无需依赖第三方。
  • 实时重新加载
  • 支持单页应用程序的客户端路由。
  • 目录列表
  • 支持HTTPS
  • 允许以模块形式进行编程使用
  • 用于快速原型制作的样板。
  • 可注入的 HTTP 请求拦截器。(TS 和 JS)

入门

安装为 Deno 可执行文件。

注意:Deno 默认是一个安全的运行时。你需要添加--allow-net--allow-read--allow-write标志,以确保 Denoliver 能够为你的目录提供服务。

$ deno install --allow-net --allow-read --allow-write --allow-run https://deno.land/x/denoliver/mod.ts

或者如果你对这个名字不满意:

$ deno install -n whateverNameYouWant --allow-net --allow-read --allow-write --allow-run https://deno.land/x/denoliver/mod.ts

我为什么需要这--allow-run面旗帜?

你不需要它! ...




结束语

2020年对每个人来说都是一段有趣的时光。我很荣幸能够说,自己在这段时间里成长了很多,而这其中的功劳,很大程度上要归功于这个小小的过程。

这或许看似无关紧要,但我强烈建议每天花几分钟时间反思你所获得的知识,并用你选择的媒介记录下来。没有什么太大或太小。到年底,或者可能更早,你会对自己所获得的知识感到惊讶。

希望您喜欢我今天日记中的小花絮。

今年你学到了什么?

文章来源:https://dev.to/joakimdevelops/10-things-2020-has-taught-me-nfj
PREV
第 002 集 - 项目结构加第一个应用程序 - ASP.NET Core:从 0 到过度
NEXT
保持冷静,拒绝编码挑战