我是新手,jQuery的。 我有点糊涂了是否是罚款或可能导致内存泄漏?
下面是代码:这种方法被称为在特定日期过滤器为每一个新值
function preapreTooltip(chart) {
var tickLength = chart.xAxis[0].tickPositions.length,
ticks = chart.xAxis[0].ticks,
tickPositions = chart.xAxis[0].tickPositions;
for ( var iCntr = 0; iCntr < tickLength; iCntr++) {
var tickVal = tickPositions[iCntr];
//.label or .mark or both
(function(tickVal) { // Is this good practice to call function like this?
ticks[tickVal].label
.on('mouseover', function(event) { // Is this good practice to call function like this?
var label = '', labelCnt=0;
$(chart.series).each(function(nCntr, series) {
//business logic for each series
});
// calling method to show values in a popup
});
ticks[tickVal].label.on('mouseout', function(event) { // Is this good practice to call function like this?
try {
hideWrapper(); // hides popup
} catch (e) {
// do nothing
}
});
})(tickVal);
}
}
虽然有需要编写大型纯JavaScript项目时,使用如jQuery应该假定库的设计有助于你避免这些问题库时要避免浏览器的具体问题。 但是,考虑到内存泄漏是相当难以追查,每个版本不同的特定浏览器中可以表现不同 - 它是更好的懂得一般避免内存泄漏不是被特定的:
- 如果你的代码被重复多次,以确保您使用的变量可以被垃圾收集被丢弃,并且在关闭引用不绑起来。
- 如果你的代码是处理大型数据结构,请确保您有删除或抵消数据的方式。
- 如果你的代码构造许多对象,功能和事件监听器 - 它始终是最好的,包括一些解构代码了。
- 尽量避免javascript对象或功能直接附连到元件作为属性-即
element.onclick = function(){}
- 如果有疑问,总是在你的代码完成整理。
你似乎认为这是调用,将会对泄漏的影响函数的方式,但它始终是更可能是那些可能导致问题的功能的内容。
有了上面的代码,我唯一的建议是:
每当使用事件侦听器试图找到一种方式来重复使用的功能,而不是创建每个元素之一。 这可以通过使用来实现事件代表团 (诱捕上的祖先/父事件,并委派反应到event.target
),或编码一个单一的普通函数来处理你的元素在一种相对的方式,最常相对于this
或$(this)
。
当需要创建许多事件处理程序,它通常是最好的这些事件侦听器存储为命名的功能,这样你就可以在完成时,再把它们去掉。 这意味着使用匿名函数,你正在做的避免。 但是,如果你知道这只是你的代码处理DOM中,你可以回退到使用$(elements).unbind('click')
删除所有点击处理(匿名或不)使用jQuery选定的元素应用。 如果你这样做不过使用这种后一种方法,它肯定是更好地使用jQuery的事件命名空间的能力 - 让你知道你只是删除您的活动。 即$(elements).unbind('click.my_app');
。 显然,这意味着你必须使用绑定的事件$(elements).bind('click.my_app', function(){...});
更加具体:
自动调用一个匿名函数
(function(){
/*
running an anonymous function this way will never cause a memory
leak because memory leaks (at least the ones we have control over)
require a variable reference getting caught in memory with the
JavaScript runtime still believing that the variable is in use,
when it isn't - meaning that it never gets garbage collected.
This construction has nothing to reference it, and so will be
forgotten the second it has been evaluated.
*/
})();
添加一个匿名事件侦听器使用jQuery:
var really_large_variable = {/*Imagine lots of data here*/};
$(element).click(function(){
/*
Whilst I will admit not having investigated to see how jQuery
handles its event listeners onunload, I doubt if it is auto-
matically unbinding them. This is because for most code they
wont cause a problem, especially if only a few are in use. For
larger projects though it is a good idea to create some beforeunload
or unload handlers that delete data and unbind any event handling.
The reason for this is not to protect against the reference of the
function itself, but to make sure the references the function keeps
alive are removed. This is all down to how JS scope works, if you
have never read up on JavaScript scope... I suggest you do so.
As an example however, this anonymous function has access to the
`really_large_variable` above - and will prevent any garbage collection
system from deleting the data contained in `really_large_variable`
even if this function or any other code never makes use of it.
When the page unloads you would hope that the browser would be able
to know to clear the memory involved, but you can't be 100% certain
it will *(especially the likes of IE6/7)* - so it is always best
to either make sure you set the contents of `really_large_variable` to null
or make sure you remove your references to your closures/event listeners.
*/
});
拆解和解构
我一直在关注 - 对于我的解释 - 网页时不再需要与用户浏览外出。 然而上述变得即使在今天的世界ajaxed含量和高动态界面更相关; 图形用户界面正在不断地创造和捣毁元素。
如果要创建一个动态JavaScript应用程序,我不能强调它是多么的重要与构造.tearDown
或.deconstruct
当不再需要的代码被执行的方法。 这些应该逐步完成大量自定义对象结构和抵消他们的内容,以及删除事件侦听器,并已动态创建和不再使用的元素。 你也应该使用jQuery的empty
替换元素的内容之前的方法-这可能是用他们的话说更好地解释:
http://api.jquery.com/empty/
以避免内存泄漏,jQuery的去除元件本身之前除去其他结构,例如从子元素数据和事件处理程序。
如果你想删除元素而不破坏他们的数据或事件处理程序(这样他们就可以在以后重新加入),使用.detach()代替。
力不仅与拆卸方法编码你这样做更整齐(即确保你保持命名空间将彼此相关的代码,事件和元素),它通常意味着你在一个更模块化的方式建立的代码; 这是面向未来的你的应用程序,用于读取能力,并且为别人谁可以接替你的项目在以后的日子明显好得多。
这里是一个极好的制品使用浏览器或Safari检测内存泄漏: http://javascript.crockford.com/memory/leak.html
它是使用开发者工具面板中不为人所熟知的功能。
有趣和非常有益的!
编辑
这是不好的链接(但仍然有用)。 这里是一个: http://gent.ilcore.com/2011/08/finding-memory-leaks.html