javascript - jQuery 事件是否会在销毁它们所绑定(bind)的内容时自动解除绑定(bind)?

标签 javascript jquery jquery-events

如果我在一个对象的两个函数中有如下代码:

add: function()
{
    // create trip.
    var trip = new Trip();

    // add the trip using its id.
    this.trips[trip.id] = trip;
},

remove: function(tripId)
{
    // remove trip.
    delete this.trips[tripId];
}

注意:Trip 对象的构造函数将一堆自定义 jQuery 事件处理程序绑定(bind)到自身。

Trip对象被删除时绑定(bind)到Trip对象的事件处理器会自动销毁/清理吗?

如果 DOM 节点被删除并绑定(bind)了事件处理程序,是否会发生同样的情况?

我还读到,对象不会被垃圾收集器清理,直到所有对它们的引用都不再存在,所以绑定(bind)到对象的事件处理程序本身也算作引用并阻止对象被清理,即使我不再引用它了吗?

最佳答案

事件不会被删除,因为 jQuery 维护着所有绑定(bind)事件处理程序的中央存储库,并且知道您是否或何时使用 delete 删除了关联对象。 .试试这个小测试来确认。 (仅限 jQuery 1.4.2)

jsfiddle link :

// 1. a regular JS object
var root = {};
// Since we can't delete anything created with var (except on Chrome),
// we use an object property here. An array value works just as well,
// which is already the case in your example.
root.o = {};

// 2. at this point, jQuery creates an internal property
// jQuery<UNIQ_ID>, for example jQuery1277242840125 inside object o
$(root.o).bind("myEvent", function() { alert("here"); });

// 3. get the *internal* index jQuery assigned this object:
// there's only 1 property, so we just enumerate and fetch it.
var internalIndex;
for(var prop in root.o) {
    internalIndex = root.o[prop];
}

// 4. delete the object
delete root.o;

// 5. query jQuery internal cache with the internal index from step 3
console.log(jQuery.cache[internalIndex].events);
​

第 5 步应记录与 ex-o 对象关联的所有事件类型的数组,包括“myEvent”及其关联的处理程序,因此绑定(bind)的事件处理程序不会自动删除。这是我看到的记录内容(删除了不相关的属性):

▾ Object
  ▾ myEvent: Array (1)
    ▾ 0: Object
      ▸ handler: function () { alert("here"); }
        namespace: ""
        type: "myEvent"
      length: 1

然而,对象删除不受影响,将按预期删除。然而,这是一种情况,因为在 jQuery 缓存中的某处有相关数据将保留在那里。

看起来虽然您可以将事件绑定(bind)到纯 JavaScript 对象,但您无法解除绑定(bind)。 jQuery 似乎在解除绑定(bind)时假定对象是 DOM 节点,并抛出以下错误:

Uncaught TypeError: Object #<an Object> has no method 'removeEventListener'

我相信,即使是关于能够将事件绑定(bind)到对象的部分也没有记录在案。所以你必须对此小心一点,因为在尝试清理该对象的事件处理程序引用时,以下内容将不起作用:

<罢工>

<罢工>
$(object).remove()
$(object).unbind(..)

<罢工>

作为解决方法,在清理 Trip 对象时,您可以显式调用 removeData完成这项工作。

$(object).removeData();

正如我已经提到的,它越来越深入 jQuery 的内部结构,因此您可能想要查看替代解决方案,或者提防库升级很容易破坏您的代码,这不太可能。

关于javascript - jQuery 事件是否会在销毁它们所绑定(bind)的内容时自动解除绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3096033/

相关文章:

javascript - 根据页面宽度 javascript 更改 CSS?

javascript - 为什么这不想在动态内容上找到选择器?

javascript - 停止触发 ajax 请求

javascript - JQuery $(window).focusout 问题

javascript - 在 JavaScript 中,将配置常量放在同一个模块文件或单独的配置文件中更好

javascript - 如何测试指令链接中定义的 $on 事件

javascript - 如何访问事件监听器之外的变量?

javascript - HTML li ul 下拉菜单层次结构

javascript - CSS::contenteditable 中元素的焦点

jquery - 如何在 $.ajax 中覆盖 jQuery 对 XMLHttpRequest 的使用?