Gav*_*vin 3 javascript jquery javascript-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];
}
Run Code Online (Sandbox Code Playgroud)
注意:Trip对象的构造函数将一堆自定义JQuery事件处理程序绑定到自身.
删除Trip对象时,是否会自动销毁/清除绑定到Trip对象的事件处理程序?
如果dom节点被删除并且事件处理程序绑定到它,那么会发生同样的情况吗?
此外,我读到垃圾收集器不会清除对象,直到对它们的所有引用都不再存在,因此绑定到对象的事件处理程序本身作为引用计数并防止对象被清除,即使我不是更长时间的引用?
该事件不会被删除,因为jQuery维护所有绑定事件处理程序的中央存储库,并且确实知道是否或何时使用删除了关联对象delete.尝试这个小测试来确认.(仅限jQuery 1.4.2)
// 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);
?
Run Code Online (Sandbox Code Playgroud)
步骤5应记录与ex-o对象关联的所有事件类型的数组,包括"myEvent",以及它的关联处理程序,因此不会自动删除绑定事件处理程序.这是我看到的记录(剥离不相关的属性):
? Object
? myEvent: Array (1)
? 0: Object
? handler: function () { alert("here"); }
namespace: ""
type: "myEvent"
length: 1
Run Code Online (Sandbox Code Playgroud)
但是,对象删除不受影响,并且将按预期删除.然而,由于jQuery的缓存中存在关联数据,因此它仍然存在于某种情况下.
看起来虽然您可以将事件绑定到纯JavaScript对象,但您无法取消绑定它们.看来jQuery假定对象在解绑定时是一个DOM节点,并抛出以下错误:
Uncaught TypeError: Object #<an Object> has no method 'removeEventListener'
Run Code Online (Sandbox Code Playgroud)
我认为,即使是能够将事件绑定到对象的部分也没有记录.所以你必须对此有点小心,因为在尝试清理该对象的事件处理程序引用时,以下内容将不起作用:
$(object).remove()
$(object).unbind(..)
Run Code Online (Sandbox Code Playgroud)
作为一种解决方法,在清理Trip对象时,您可以显式调用removeData来完成这项工作.
$(object).removeData();
Run Code Online (Sandbox Code Playgroud)
正如我已经提到的那样,jQuery的内部结构已经变得过于紧张,所以你可能想看一个替代解决方案,或者担心库升级很容易破坏你的代码,这不太可能.