我有一个绑定不同表单输入的函数
function bindInputs() {
$(".inputContainer").each(function(i){
var inputContainer = $(this),
input = $("input.input", inputContainer),
inputType = inputContainer.attr("data-inputType"),
input_Id = inputContainer.attr("id").replace("inputContainer_", "");
if(inputType == "TextEditor") {
input.unbind("change").bind("change", function() {
inputContainer.removeClass("nullValue");
var value = input.val();
saveInputValue(input_Id, value);
});
return true;
}
if(inputType == "NumericEditor") {
input.numeric({ allow: "." });
input.unbind("change").bind("change", function() {
inputContainer.removeClass("nullValue");
var value = getNumericValue(input.val());
saveInputValue(input_Id, value);
});
}
// so on
});
};
此功能是否会造成内存泄漏?我担心的是我将所有共享变量放在最上面并在“更改”回调函数中使用它们。
如果我重新计算回调函数上的共享变量会有所作为吗?
if(inputType == "TextEditor") {
input.unbind("change").bind("change", function() {
var elem = $(this),
inputContainer = elem.closest(".inputContainer"),
input_Id = inputContainer.attr("id").replace("inputContainer_", "");
inputContainer.removeClass("nullValue");
var value = input.val();
saveInputValue(input_Id, value);
});
return true;
}
答案 0 :(得分:6)
它没有创建泄漏。只要这些函数在内存中, 就会将这些变量保留在内存中。
您是否愿意这样做取决于您,这是一个权衡。对于change
处理程序,重新查询DOM的开销很小,因此您可以使用第二个示例,尽管您在该示例中保留的实际内存影响相当小。在mousemove
处理程序中,您可能会采用相反的方式,因为mousemove
处理程序需要非常快速地完成工作。
在下面的评论中重新提问:
说我会选择第二种方法,我将如何阻止浏览器保存顶级变量?我在函数的末尾将它们设置为null?
如果您要使函数不依赖于bindInputs
函数中的任何,请将它们完全定义在它之外。然后,您不会在调用bindInputs
的上下文中创建任何闭包,并且该上下文可以是GC(以及它包含的任何变量)。将变量设置为null
或undefined
只需将它们设置为null
或undefined
,它就不会消除它们。 (虽然在那时,包含它们的上下文非常小。只有三到四个变量没有特别引用。)
这可能是这样的:
function bindInputs() {
$(".inputContainer").each(function(i){
var inputContainer = $(this),
input = $("input.input", inputContainer),
inputType = inputContainer.attr("data-inputType");
if(inputType == "TextEditor") {
input.unbind("change").bind("change", handleTextEditorChange);
return true;
}
if(inputType == "NumericEditor") {
input.numeric({ allow: "." });
input.unbind("change").bind("change", handleNumericEditorChange);
}
// so on
});
}
function handleTextEditorChange() {
// ...implementation...
}
function handleNumericEditorChange() {
// ...implementation...
}