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

Why does Event Delegation save memory?

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

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

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

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

中创建 100 个条目

但是如果你使用事件委托,你只需要调用 addEventListener() 一次,所以 table 中只有 1 个条目。

您实际上可以通过在开发者工具的 Elements 面板中打开 Event Listeners 选项卡来查看此数据的表示形式。

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

另一方面,当您使用委托时,回调函数需要做额外的工作来确定事件目标是否是合适的嵌套元素。这使得它有点慢。如果事件是在容器元素中的元素上触发的,但不是您委托给的元素之一(并且会 运行 随着事件冒泡而重复),它也会被调用,所以函数是 运行 更频繁。如果内存真的很宝贵,这将是一个 classic time/space 权衡。

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