gpt4 book ai didi

JavaScript 内存泄漏

转载 作者:行者123 更新时间:2023-12-03 21:51:40 25 4
gpt4 key购买 nike

我正在使用 jquery 并做类似的事情

DOM:

<div id="parent"></div>

JS:

var _doSomeThing = function()
{
//some codes
}

$(function()
{
// appending div and binding methods to span
$('#parent').append('<span>1</span>');
$('#parent').append('<span>2</span>');
$('#parent span').bind('click', _doSomeThing);
});

function _clearDiv()
{
//clear div
$('#parent').html('');
}

//sometime in future, call clear div
_clearDiv();

现在我的问题是,将事件绑定(bind)到 DOM,然后从 DOM 中删除元素是否会导致内存泄漏?

如果是,如何解决这个问题?

最佳答案

jQuery html 方法尝试通过删除因在 jQuery 上调用 .html('') 而删除的任何元素的事件处理程序来防止内存泄漏对象。

来自1.4.2源码

html: function( value ) {
if ( value === undefined ) {
return this[0] && this[0].nodeType === 1 ?
this[0].innerHTML.replace(rinlinejQuery, "") :
null;
}
// See if we can take a shortcut and just use innerHTML
// THE RELEVANT PART
else if ( typeof value === "string" && !rnocache.test( value ) &&
(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {

value = value.replace(rxhtmlTag, fcloseTag);

try {
for ( var i = 0, l = this.length; i < l; i++ ) {
// Remove element nodes and prevent memory leaks
if ( this[i].nodeType === 1 ) {
jQuery.cleanData( this[i].getElementsByTagName("*") );
this[i].innerHTML = value;
}
}

// If using innerHTML throws an exception, use the fallback method
}
catch(e) {
this.empty().append( value );
}
}
else if ( jQuery.isFunction( value ) ) {
this.each(function(i){
var self = jQuery(this), old = self.html();
self.empty().append(function(){
return value.call( this, i, old );
});
});

}
else {
this.empty().append( value );
}
return this;
}

我们可以看到调用了jQuery.cleanData()函数。这是其来源

cleanData: function( elems ) {
var data, id, cache = jQuery.cache,
special = jQuery.event.special,
deleteExpando = jQuery.support.deleteExpando;

for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
id = elem[ jQuery.expando ];

if ( id ) {
data = cache[ id ];

if ( data.events ) {
for ( var type in data.events ) {
if ( special[ type ] ) {
jQuery.event.remove( elem, type );

} else {
removeEvent( elem, type, data.handle );
}
}
}

if ( deleteExpando ) {
delete elem[ jQuery.expando ];

} else if ( elem.removeAttribute ) {
elem.removeAttribute( jQuery.expando );
}

delete cache[ id ];
}
}
}

这会在 jQuery.cache 对象中查找与调用 .html('' 时将被删除的每个元素相关的数据对象的 events 对象属性上的任何事件类型属性) 并删除它们。

为了基本上解释标准事件绑定(bind)的工作原理,当使用 jQuery 将函数作为处理程序绑定(bind)到元素上引发的事件时,数据对象将作为属性添加到 jQuery.cache 对象。该数据对象包含一个事件属性对象,该对象将在其上创建一个属性,其名称与您希望将事件处理函数绑定(bind)到的事件类型相匹配。此属性将包含一个函数数组,当在元素上引发事件时应调用这些函数,因此事件处理程序函数将添加到此数组中。如果这是相关事件类型和元素的第一个事件处理函数,则调用 apply 的 jQuery.event.handle 函数(使用该元素作为上下文,这样 this 在函数执行上下文中将引用该元素)使用 addEventListener/attachEvent 向浏览器注册。

当引发事件时,jQuery.event.handle 函数将调用与事件类型和事件匹配的数据对象的 events 属性对象的属性上的数组中的所有函数。引发事件的元素。

总而言之,html('') 不应导致内存泄漏,因为有许多防御措施可以防止内存泄漏。

关于JavaScript 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2316726/

25 4 0
文章推荐: jquery - 如何让 Google Analytics 跟踪 AJAX 调用的页面?
文章推荐: asp.net - 从谷歌财经、雅虎财经或交易所本身获取股票报价
文章推荐: javascript - 如何检查光标是否位于某个元素上?
文章推荐: javascript - jquery $ ('