使用 Maps 和 WeakMaps 可以提高代码的可读性和可维护性 。将DOM节点与相关数据关联起来,有助于使代码更清晰易懂 。

文章插图
这篇文章讨论了使用 Maps 和 WeakMaps 处理DOM节点的优势 。Maps 和 WeakMaps 是非常实用的工具,尤其在处理大量DOM节点时,它们发挥着重要作用 。
文章作者认为,使用 Maps 和 WeakMaps 处理 DOM 节点有以下几个优点 。首先,它们可以方便地存储和检索数据 。与其他数据结构相比,Maps和 WeakMaps 可以更简洁地组织和查找相关数据 。其次,它们可以帮助开发者更好地管理内存 。当不再需要某个DOM节点时,WeakMaps可以自动释放与该节点相关的内存,从而提高程序的性能 。最后,使用 Maps 和 WeakMaps 可以提高代码的可读性和可维护性 。将DOM节点与相关数据关联起来,有助于使代码更清晰易懂 。
下面是正文:
在JAVAScript中, 我们经常使用普通的对象来存储键/值数据,它们非常擅长这项工作 - 清晰易读:
const person = { firstName: 'Alex',lastName: 'macArthur',isACommunist: false};但是,当我们开始处理经常被读取、更改和添加属性的较大实体时,更倾向于使用 Maps 。因为在某些情况下,Map 比对象具有多个优势,特别是性能问题或插入顺序比较重要的情况下 。但最近我特别喜欢使用它们来处理大量的DOM节点 。
在阅读Caleb Porzio最近的博客文章时,我想到了这个想法 。在这篇文章中,他正在使用由10,000个表行组成的表格,其中一个可以是“active” 。为了管理选择不同行时的状态,使用对象作为键/值存储 。这是他的一个迭代版本的注释版本 。
import { ref, watchEffect } from 'vue';let rowStates = {};let activeRow;document.querySelectorAll('tr').forEach((row) => {// Set row state.rowStates[row.id] = ref(false);row.addEventListener('click', () => {// Update row state.if (activeRow) rowStates[activeRow].value = https://www.isolves.com/it/cxkf/qd/2023-05-22/false;activeRow = row.id;rowStates[row.id].value = true;});watchEffect(() => {// Read row state.if (rowStates[row.id].value) {row.classList.add('active');} else {row.classList.remove('active');}});});它使用一个对象作为大型哈希映射表,因此用于关联值的键必须是字符串,因此需要在每个项目上存在唯一的ID(或其他字符串值) 。这带来了一些额外的编程开销,需要在需要时生成和读取这些值 。任何对象都可以作为键相反,使用 Map 可以让我们直接将 html 节点作为键 。因此,该代码片段最终看起来像这样:
import { ref, watchEffect } from 'vue';- let rowStates = {};+ let rowStates = new Map();let activeRow;document.querySelectorAll('tr').forEach((row) => {- rowStates[row.id] = ref(false);+rowStates.set(row, ref(false));row.addEventListener('click', () => {-if (activeRow) rowStates[activeRow].value = https://www.isolves.com/it/cxkf/qd/2023-05-22/false;+if (activeRow) rowStates.get(activeRow).value = false;activeRow = row;-rowStates[row.id].value = true;+rowStates.get(activeRow).value = true;});watchEffect(() => {-if (rowStates[row.id].value) {+if (rowStates.get(row).value) {row.classList.add('active');} else {row.classList.remove('active');}});});这里最明显的好处是我不需要担心每行存在唯一ID 。节点引用本身是唯一的,可以作为键 。因此,既不需要设置也不需要读取任何属性 。这更简单、更具弹性 。读/写操作通常更高效当我们处理更大的数据集时,操作的性能显著提高 。甚至在规范中也有说明 - 必须以保持性能的方式构建
Map,以便随着项目数量的增加而增长:Maps must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection.“Sublinear” 的意思是性能不会随着 Map 的大小成比例地下降 。因此,即使是大型 Map,性能也应该保持相当迅速 。
再次强调,没有必要干扰DOM属性或通过类似字符串的ID执行查找 。每个键本身就是一个引用,这意味着我们可以跳过一两个步骤 。
我进行了一些基本的性能测试来确认所有这些 。首先,按照Caleb的场景,我在页面上生成了10,000个 <tr> 元素:
const table = document.createElement('table');document.body.Append(table);const count = 10_000;for (let i = 0; i < count; i++) {const item = document.createElement('tr');item.id = i;item.textContent = 'item';table.append(item);}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 数据结构与算法 --- “哨兵”思想
- 工厂模式:将对象的创建与使用分离,提高程序可维护性和可扩展性
- 从不同维度分析:Linux与Windows的区别
- 林峰|张馨月晒全家福,与林峯带女儿打高尔夫,Luna从小被当名媛培养
- 季先生的心尖宠|《季先生的心尖宠》爱与成长的交织,畅快追爱的青春之旅
- |李小璐出轨风波后正式复工,发文解释与贾乃亮复婚传闻
- 孟晚舟|孟晚舟丈夫出席儿子成人礼,现任妻子露脸现身,相貌与前妻神似
- |何超莲与杨颖同框气质出众!家姐何超琼称赞窦骁,情商高很有礼貌
- Angelababy|李嘉诚准儿媳梁洛施,直言与李泽楷分手后,感情更比从前
- |黄花梨收藏与鉴赏
