为什么事件委托可以节省内存?

问题描述

我试图了解添加事件时“addEventListener”的工作原理,它保存在哪里? DOM 树?还是某个记忆的地方?但是找不到答案,我见过的所有帖子都说“你不能”,因为它没有标准,每个浏览器都有不同的实现。

所以我试图跳过它,但有一个关于事件委托的问题。在很多帖子中,人们说事件委托可以节省内存,因为我们不必为每个组件附加事件侦听器。但我想,我必须了解 addEventListener 是如何工作的,才能理解为什么事件委托可以节省内存。

那么事件委托的内存效率高的原因是什么?

解决方法

在浏览器内存中的某处,有一个数据结构,其中包含每个元素的事件侦听器列表。如果您为 100 个不同的元素分别调用 addEventListener(),它将在此表中创建 100 个条目。

但如果您使用事件委托,则只需调用 addEventListener() 一次,因此表中只有 1 个条目。

您实际上可以通过打开开发者工具元素面板中的事件监听器标签来查看这些数据的表示。

但是,您节省的内存量可能不是很大。每个侦听器可能只是几个指针,一个指向表示事件类型(单击、更改等)的内容,另一个指向回调函数。如果所有 100 个事件侦听器都调用同一个函数,则只有一个函数对象和 100 个指向它的指针。如果函数是闭包,也会有一个环境对象包含它关闭的变量,这会增加一点内存使用,但不会太多。

另一方面,当您使用委托时,回调函数需要做额外的工作来确定事件目标是否是合适的嵌套元素。这让它慢了一点。如果事件是在容器元素中的元素上触发的,但不是您委派给的元素之一(并且会在事件冒泡时重复运行),它也会被调用,因此该函数会更频繁地运行。如果内存真的很珍贵,这将是一个经典的时间/空间权衡。

实际上,委托不是用来节省内存的,而是用来简化设计的。当您向 DOM 动态添加元素或更改事件绑定所依赖的属性(例如类名)时,它最常使用。委托允许您定义事件侦听器一次,而不必在添加或修改元素时从元素中添加或删除它。