这个问题是关于jQuery函数如何保存HTML元素,以及是否会对垃圾回收产生影响。
考虑以下两个函数,它们显示或隐藏HTML页面中的某个
function showError() { $("div#error").show(); }
function hideError() { $("div#error").hide(); }
这两个函数总是调用jQuery在DOM树中找到
var divError = $("div#error");
function showError() { divError.show(); }
function hideError() { divError.hide(); }
但是,在这种情况下,
divError
变量在全局范围内被松散了。我们可以用一个函数拉一些技巧:var showError, hideError;
(function() {
var divError = $("div#error");
showError = function() { divError.show(); }
hideError = function() { divError.hide(); }
})();
在所有这些情况下,对垃圾回收有何影响?在全局范围内浮动对jQuery函数的调用结果是否有问题?
尝试最大程度地减少对jQuery函数的调用是否是一个好的准则?这些例子应该遵循还是避免?
如果我在这些示例中用
document.getElementById()
替换了jQuery,以检索HTML元素,是否存在同样的问题?
最佳答案
垃圾收集
如果您正在执行其中的一些操作,请不要担心。如果单独使用此处显示的任何一种用户案例,都不会对内存使用产生负面影响。
内存占用
当大循环执行时,这些将开始产生潜在的影响。 Each time a function object is created, it can take up to 754 bytes of memory。如果您创建许多此类文件(例如1000),则可能会短暂占用1MB的内存,具体取决于可忽略的浏览器。 10,000会变得更糟(〜10MB),100,000(〜100MB)会变得很麻烦,而1,000,000(〜1GB)可能会开始以几分钟的UI锁定形式出现严重问题,具体取决于客户端。
范围
当对象未保留在当前执行上下文中时,垃圾回收器将成为先前情况的一个因素。每个执行上下文都有一个词法和可变环境。一旦当前执行上下文失去作用域,可变环境就是可以进行垃圾回收的环境。但要注意的是,“合格”仅表示它将在某个时间发生,并且不保证何时进行。
为了减轻内存占用量的增长,确保实现函数的执行上下文以使其尽快失去作用域,将确保垃圾收集器具有尽快收集垃圾的选项。同样,收集选项可能在一段时间内无法实现。
实作
这一切都是通过封闭变量来完成的,因此一旦引用消失,它们便有资格在将来方便垃圾回收器的某个时候进行收集。
性能
除此之外,如果单独使用,则调用jQuery函数的关注应该不重要。重复查询成为唯一的问题是,当您有大约10,000个以上的DOM元素时,此时您可能已经遇到了其他问题。而当您要迭代数千次并且想要避免累积毫秒数时。优化总耗时少于10毫秒的任何事物,可能都是微优化。 10至100是酌情决定的,绝对应保证超过100。
此外,每当通过id访问元素时,都可以通过O(1)的字典(哈希表)查找直接访问它。这意味着您的DOM不需要完全解析。但是,情况并非总是如此,因此我假设我们不能简单地停在那里。
因此,如果仅使用一次,则您的第一种情况(在这里无需使用div,id是O(1)查找)就没有问题。
function showError() { $("#error").show(); }
function hideError() { $("#error").hide(); }
但是,如果出于某种原因,id的字符串是类选择器,并且在某种程度上以循环方式进行大量处理,则需要确保函数定义的作用域是循环,并且元素选择器是缓存(缓存本身确实引入了一种有趣的附带情况,其中缓存的元素集实际上可能与动态页面中的类选择器之类的页面集不匹配,但这只是一种边缘情况)。
范围
父作用域很重要,因为您从不真正希望在全局作用域中执行代码。因此,尽管这两个完成相同的任务
var divError = $("div#error");
function showError() { divError.show(); }
function hideError() { divError.hide(); }
和
var showError, hideError;
(function() {
var divError = $("div#error");
showError = function() { divError.show(); }
hideError = function() { divError.hide(); }
})();
(请注意,因为IIFE中的匿名函数的词法环境引用了其可变环境,因此,除非该词法环境符合条件,否则它不符合垃圾回收的条件)
他们对范围的处理略有不同。第一个将公开变量divError,而第二个则不公开。在狭窄的环境中,这无关紧要,因为在词法和可变环境中发生冲突的可能性较小,但是在全局命名空间中,这可能是有问题的,因为要等到整个页面卸载后才收集词法环境。这称为polluting the global namespace。
备择方案
最后,整个分析归结为一些本来应该是微不足道的事情。如果要全局访问此元素,则将其存储在已安全使用的全局变量中。由于您使用的是jQuery,因此只需使用$。
$.errorDiv = $("#error");
当您要切换状态时,只需使用toggle :)或隐藏/显示,如果您不确定状态或以某种方式将其显示两次。
$.errorDiv.toggle();
$.errorDiv.show();
$.errorDiv.hide();
据我了解,最后一节可能并不直接适用,因为这可能是类似行为的简单再现。
关于jquery - jQuery函数对垃圾回收有影响吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29569668/