Javascript闭包变量的性能

时间:2012-12-12 09:54:04

标签: javascript jquery performance

我有一个绑定不同表单输入的函数

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;
}

1 个答案:

答案 0 :(得分:6)

它没有创建泄漏。只要这些函数在内存中, 就会将这些变量保留在内存中。

您是否愿意这样做取决于您,这是一个权衡。对于change处理程序,重新查询DOM的开销很小,因此您可以使用第二个示例,尽管您在该示例中保留的实际内存影响相当小。在mousemove处理程序中,您可能会采用相反的方式,因为mousemove处理程序需要非常快速地完成工作。

在下面的评论中重新提问:

  

说我会选择第二种方法,我将如何阻止浏览器保存顶级变量?我在函数的末尾将它们设置为null?

如果您要使函数不依赖于bindInputs函数中的任何,请将它们完全定义在它之外。然后,您不会在调用bindInputs的上下文中创建任何闭包,并且该上下文可以是GC(以及它包含的任何变量)。将变量设置为nullundefined只需将它们设置为nullundefined,它就不会消除它们。 (虽然在那时,包含它们的上下文非常小。只有三到四个变量没有特别引用。)

这可能是这样的:

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...
}