Map和WeakMap更适合处理大量 DOM 节点

2023-08-031965次阅读原生Jsjavascript

Map(和 WeakMap)更适合处理大量 DOM 节点

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 = 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。节点引用本身——本质上是唯一的——充当键。因此,不需要设置或读取任何属性。它更简单、更有弹性。

WeakMaps更有效地管理内存

<ul>
  <li id="item1">first</li>
  <li id="item2">second</li>
  <li id="item3">third</li>
</ul>
(async () => {
	const listMap = new WeakMap();

	// Stick each item in a WeakMap.
	document.querySelectorAll('li').forEach((node) => {
		listMap.set(node, node.id);
	});

	const registry = new FinalizationRegistry((heldValue) => {
		// Garbage collection has happened!
		console.log('After collection:', heldValue);
	});

	registry.register(document.getElementById('item2'), listMap);
    
	console.log('Before collection:', listMap);

	// Remove node, freeing up reference!
	document.getElementById('item2').remove();

 	// Periodically create a bunch o' objects to trigger collection.
 	const objs = [];
 	while (true) {
   		for (let i = 0; i < 100; i++) {
			objs.push(...new Array(100));
		}

		await new Promise((resolve) => setTimeout(resolve, 10));
	}
})();

原文:https://www.macarthur.me/posts/maps-for-dom-nodes

上一篇: Map相对于Object对象的优势  下一篇: 没有了~

Map和WeakMap更适合处理大量 DOM 节点相关文章