JavaScript 集合指南
在 JavaScript 中,集合是一个集合,一组数据,可以由具有不同行为的各种类型的数据组成。数据的集合可以具有各种数据类型,或者该集合本身可以是特定的数据结构。
如果您还没有阅读过这篇文章,我建议您阅读我关于JavaScript 中的数据类型和数据结构的文章。
Javascript 中可以有 3 种类型的集合:
- 索引集合
- 键控集合
- DOM集合
索引集合
索引集合包含按索引排序的数据,也可以使用该索引进行访问。索引表示数据的位置。例如,想象人们在排队。距离计数器最近的人的索引为 0,因此他们位于位置 0。下一个人的索引为 1,然后下一个人的索引为 2,依此类推。在 JavaScript 中,索引始终从 0 开始。
索引集合可以是 Array 或 TypedArray。让我们逐一介绍一下。
大批
最流行和众所周知的数据集合是数组。数组是有序元素的索引集合,这些元素有自己的索引,并且可以通过该索引进行访问。数组可以包含任何数据类型,甚至其他数组。常规数组不是基于类型的。这意味着您不必定义要在数组内使用的数据类型。您可以随时一起使用所有东西。
创建数组
创建数组的方法有多种。最简单、最现代的方法是创建一个值为空方括号的变量。稍后或立即,您可以将所需的任何数据放在那里。
访问数组元素
要超出数组项,您可以简单地使用目标项的索引(位置)。只是不要忘记索引从 0 开始,因此第一个元素是索引 0,而不是 1。
破坏数组
析构是一种以最有效的方式从数组中提取数据的方法。数组有时可能非常复杂,甚至有多个级别。
从数组中检索元素的最简单且初学者很容易理解的方法是通过索引定位元素。例如,如果您需要特定的项目,您可以计算其索引并检索该元素。
看起来很容易,对吧?但假设我想检索更多。
但如果我有 100 个元素怎么办?您将花费大量时间将所有内容一一检索。通过使用解构,我们可以最大限度地减少代码和时间。
现在看起来更短更容易了。正如您所看到的,我将新的变量名称放置在数组中,每个变量都按其位置与数组中的值匹配。我的第一个变量是苹果,第一个元素被分配给苹果。破坏的技巧有很多,这并不是唯一可以做的事情。
您只想检索第一个值并希望单独保存其余值的图像。这是绝对有可能的!
我重复了几乎相同的逻辑,但略有不同。第一个元素将被相应保存,就像以前一样。但是,为了保存其余元素,我使用其余参数(三个点)和所需的变量名称。
如果我们不使用剩余参数会发生什么?它不会保存数组中的其余元素,而是根据位置(索引)保存该元素,其余元素将被忽略。让我们使用完全相同的示例,但没有剩余参数。
您可以使用的另一个技巧是跳过特定索引。例如,您想要检索第一个和第三个元素。为此,您可以编写一个空格、一个逗号,以及下一个变量名称。
正如您所看到的,我们跳过了橙色并转到最后一个元素。
数组通常很灵活并且变化很大。如果添加的变量多于数组中的元素,会发生什么情况?没什么,它只是未定义的。
但是,这可能不方便,因为您不希望网站用户看到他们不理解的任何值。直到他们读我的帖子哈哈。要解决此问题,您还可以添加默认值,该值将替换未定义的值,直到出现实际值为止。
数组方法
数组有多种方法可以对数组执行快速操作,而无需从头开始编写所有内容。方法与 JavaScript 中已存在的函数类似(不相同),因此您无需自己创建任何内容。您可以在此处阅读有关数组方法的更多信息。
类型数组
类型化数组不是数组。它是一个类似数组的对象,特别是一个缓冲区。JavaScript 中的缓冲区是存储二进制数据的内存空间(通常是 RAM)。该缓冲区是一个类型化数组,以与数组非常相似的特定顺序存储整数。与数组相比,类型化数组一旦创建就无法更改。尽管数组和类型化数组不同,但它们确实共享几个相同的方法,但不是全部。
您可能会问它们是否如此相似,为什么首先要存在类型化数组?正如我们已经讨论过的,常规数组可以保存我们可以随时操作的任何数据。然而,网络不断发展,视频和音频等重数据的使用越来越多。浏览器处理此类数据要困难得多,因此需要更多时间和精力!当然,这比幕后更复杂,但您现在需要知道的是类型化数组存储原始数据,这些数据在浏览器中运行得更快,从而提高性能,这对于更重和更复杂的数据至关重要。
类型化数组架构
类型化数组分为两部分 - 缓冲区和视图。缓冲区只包含数据(内存)而没有其他内容,而视图通过提供上下文的数据类型(将数据转换为类型化数组的数据类型)、起始偏移量和元素数量来将此数据转换为类型化数组。
创建类型化数组
为了使用类型化数组,您需要创建一个 ArrayBuffer 然后查看它。创建视图时,您可以首先通过指示所需的大小和类型来创建视图,也可以创建数组缓冲区,然后创建指向它的视图。
视图可以是多种多样的,并且单个数组缓冲区可以具有不同的视图。
让我们为具有特定大小和类型的类型化数组创建一个视图。
我们创建了一个类型为 Uint8Array、大小为 5 的视图。我们很快就会介绍视图类型,所以如果您现在不明白它的含义也没关系。让我们看看它在控制台中显示什么。
注意零。您看到的五个零是我们之前设置的大小。但它们现在是空的,还没有数据。是时候像在数组中一样使用索引来保存一些数据了。
让我们再次查看控制台。你能猜到会发生什么变化吗?
正如您所看到的,现在索引 0 处有数字 10,索引 3 处有数字 20,正如我们设置的那样。
是时候先创建数组缓冲区,然后创建视图了,因此这是一种受人尊敬的类型化数组创建方式。
看起来很相似,对吧?正如您所理解的,结果是完全相同的。
类型数组视图
类型化数组视图可以不同,因为它们可以查看不同的数字类型,例如 Int8、Uint32、Float64 等。这完全取决于您正在处理的内容以及需要处理的数据类型。
何时使用 TypedArray
类型化数组通常与 Web API 一起使用。API 是应用程序和服务器之间的中间人。例如,当您在某个地方注册然后登录时,所有信息都会来回发送。通过使用网站,您可以向 API 询问您想要从网络服务器获得什么。
浏览器有各种使用类型化数组的内置 API。
网页GL
WebGL(Web 图形库)是第一个使用类型化数组的 API。它是一个 API,无需下载或安装任何内容即可渲染交互式 3D 和 2D 图形。对于 JavaScript,我们可以在 HTML Canvas 中渲染它。
画布 2D
此 API 还可以与 HTML Canvas 一起使用并使用类型化数组。它提供了各种方法、对象和属性来实时绘制和操作画布元素。
XMLHttpRequest Level 2
XMLHttpRequest2 API 允许 JavaScript 在浏览器中发出 HTTP 请求。在此之前,您必须将字符串解析为类型化数组,但现在您可以直接接收类型化数组响应。
文件阅读器
FileReader 是一种读取 blob 或文件内容的方法。Blob 是一种以二进制数据或文本形式读取的类似文件的原始数据。文件是一种特定类型的 blob。这就是类型化数组发挥作用的地方,因为我们必须处理二进制数据。
转换类型化数组
您可以使用 ArrayBuffer 将类型化数组从一种类型转换为另一种类型,还可以将常规数组转换为类型化数组。
要将数组转换为类型化数组,可以使用内置方法 typedArray.from() ,该方法接受三个参数 typedArray.from(source, map, arg)。源是目标数组,映射是对每个元素调用的函数的选项参数,arg 是映射函数中使用的可选值。
从一种类型化数组转换为另一种类型化数组也同样简单。您只需定位所需的类型化数组视图并传递要转换的类型化数组即可。
键控集合
键控集合是按键而不是索引排序的数据集合,由键值对组成。在 JavaScript 中,我们有两种类型的键控集合 - Map 和 Set。
地图
映射是一个简单的键值对对象,您可以在其中按插入顺序迭代元素。就像索引一样,键始终需要是唯一的。要创建地图,您可以使用地图构造函数,然后使用 set 方法添加所需的元素。键名称必须是字符串,值可以是任何数据类型。
为了访问密钥,您可以使用 get 方法和密钥名称。如果您使用不存在的键,它将返回未定义。
地图方法
地图有各种内置对象,包括最常用的 set 和 get 。
Map.prototype.clear()
此方法删除所有现有的键值对并重置映射。
Map.prototype.delete()
如果键存在并且已被删除,delete 方法将返回 true,如果不存在则返回 false。
Map.prototype.entries()
返回包含所有键值对的新迭代器对象。迭代器意味着您可以对其进行迭代,并循环遍历每个键值对。
Map.prototype.keys()
此方法与前一个方法非常相似,也返回一个仅包含键的迭代器对象。
Map.prototype.values()
此方法也是如此,但它返回的是对象的值,而不是键。
Map.prototype.forEach()
此方法的工作方式与数组中的 forEach 方法类似。它按插入顺序对映射中的每个键值对执行一个函数。
Map.prototype.has()
has 方法检查是否存在与我们传递给该方法的键关联的值。所以它返回 true 或 false。请注意,您需要传递键,而不是值。
迭代地图
要迭代地图,您可以使用 for...of 循环。要同时针对键和值,一个非常简单的方法是使用解构。
使用地图对象上的条目方法可以实现相同的效果。比较它们并找出差异。
如果您只想使用按键,则可以使用另一种按键方法。
与仅使用值的情况类似。
弱映射
JavaScript 中的弱映射也是一个键值对集合。它们看起来非常相似,但并不完全相同。在我们进一步讨论之前,让我们创建一个简单的弱映射。
地图和弱地图的区别
在弱映射中,键只能是对象(或未注册的符号),而值则更灵活。
然而,到底是什么原因才被称为弱呢?其背后的原因是这些关键对象是所谓垃圾收集的目标。
垃圾收集
JavaScript 中的垃圾收集是自动内存管理。它监视内存限额(也称为内存分配),并确定是否需要特定的内存块,如果需要则将其删除。当收集对象键时,也会收集它们各自的值,除非它们强烈引用其他对象(在本例中为对象)。
在弱映射中,您也没有方法来访问密钥,因为它们很弱。弱映射保存对键的引用,而不是键本身。
您无法像使用映射那样迭代弱映射,但它们确实共享一些类似的方法,例如 get、set、delete 和 has。
为什么我们需要弱地图?
弱映射的主要用途之一是内存泄漏。JavaScript 中的内存泄漏是 JavaScript 持续允许特定内存块且不释放它的过程。系统中未使用的内存不断堆积,内存减少,因此应用程序可能会崩溃。
未使用的内存可能会在不同的情况下发生。例如,附加到特定元素的未使用的事件侦听器。元素可能被删除,但未使用的事件侦听器仍然存在。现在想象一下很多像这样的事件监听器使用内存,但我们甚至不需要它们。内存泄漏的其他原因可能是回调、计时器(例如 setTimeout)、闭包和大型数据结构。
例如,假设您想要跟踪用户点击您网站上的广告的次数。
首先,我们将创建一个常规地图,其中用户将是键,值将是他们点击广告的次数。当用户离开网站时,我们不再需要有关点击的信息。
一旦用户对象消失,该对象将作为键保留在映射中,因此我们需要手动清除该映射,因为它不会被垃圾收集并占用内存中的空间。如果您的网站不好,可能几乎没有人访问它,但想象一下如果您有很多访问者。为了测试这一点,让我们将地图记录到控制台并查看它包含什么。
正如您所看到的,即使我们说用户的对象为 null(“空”),映射仍然保存有关用户的信息。
这就是弱地图发挥作用的地方。弱映射将“弱”引用用户对象,这将允许垃圾收集过程。我们只需用弱地图替换地图,然后看看一旦我们尝试清理它,有关用户的信息会发生什么情况。
正如您所看到的,不再有用户对象,并且弱映射被垃圾收集了!太棒了,对吧?!?!
放
Set 是另一个由值组成的键控集合。该集合的特殊之处在于您只能拥有唯一的值,并且不可能添加任何重复的数据。当您尝试添加重复值时,它将保留您首先添加的值。
让我们创建一个简单的集合来了解它是如何工作的。
接下来,我将尝试添加重复值 apple。会发生什么?
没有什么。不会添加任何东西。不会添加重复值并删除旧值。它将被忽略。您看到的苹果结果是旧值,而不是新值。因为集合中的元素是按插入顺序放置的,所以如果它是新值,它将是最后一个,而不是第一个。
设置方法
就像映射一样,集合也有多种方法。与映射相比,我们使用 add 而不是 set 来添加新值。
Set.prototype.clear()
此方法删除所有现有值并清空集合。但是,当您检查空集时,它会返回未定义。相反,您可以使用 size 属性,当它为空时它将显示 0。
Set.prototype.delete()
顾名思义,删除方法会删除我们指定的值。
Set.prototype.entries()
此方法创建一个键值的可迭代对象,在这种情况下键等于值。所以它就变成了类似地图的东西
Set.prototype.keys()
此方法返回一个包含值的可迭代对象。Set.prototype.values()完全相同。
Set.prototype.has()
就像在映射中一样,has 返回 true 或 false,具体取决于它是否具有我们传递给该方法的值。
Set.prototype.forEach()
此方法针对插入顺序中的每个值执行一个函数。
迭代集合
您可以使用 for...of 循环迭代集合。
弱集
与常规集相比,弱集是对象的集合,而集可以包含任何数据类型。弱集就像弱映射一样“松散”地保存信息,用于临时存储。就像集合一样,弱集合也有独特的元素,并且它们不重复。弱集就像弱映射一样也用于垃圾收集,因此请确保不要跳过我之前提到的有关垃圾收集的主题。
弱集还支持 add、has 和 delete 等方法,但它不能迭代,并且没有大小属性。当假设您正在跟踪您的用户并检查现在有多少人在线时,弱集用法非常适合是/否情况。但是当他们注销时,您不想保存用户的对象。就像弱映射一样,类似的逻辑也适用于弱集,因为它是垃圾收集的。
DOM集合
如果您已经有机会一起使用 HTML 和 Vanilla JavaScript,那么您很可能已经使用过 DOM 集合。网站的骨架建立在由各种标签组成的 HTML 之上。对于按钮,有一个按钮标签,对于标题,根据大小有各种标签,等等。所有这些标签都是对象。当您希望通过单击按钮来完成某些操作时,您可以在 JavaScript 的帮助下定位按钮对象。您可以定位任何 HTML 标记,并且可以对它们执行任何您想要的操作。
有时,您可能希望定位当前页面上的所有按钮。这些按钮的集合成为 DOM 集合,它是一个类似数组的集合。尽管它看起来像数组,但它更类似于索引集合。
我们来看看亚马逊主页上有多少个span标签。为了实现这一点,我们可以使用 document.getElementsByTagName("span") 来定位 span 元素。这将针对所有跨度。
哇,这么多跨度!!在这里,我们在一行中获得了所有跨度。
文章如果没看够可以,B站搜索千锋教育
- 点赞
- 收藏
- 关注作者
评论(0)