1

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

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

1 回答 1

6

它不会造成泄漏。只要这些函数在内存中,它就会将这些变量保留在内存中。

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

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

说我会选择第二种方法,我将如何防止浏览器保存顶级变量?我在函数结束时将它们设置为 null 吗?

如果您要使函数不依赖函数中的任何内容,请在bindInputs函数之外完全定义它们。然后,您根本不会在调用的上下文中创建任何闭包bindInputs,并且该上下文可以是 GC'd(以及它包含的任何变量)。将变量设置为nullorundefined只是将它们设置为nullor 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...
}
于 2012-12-12T09:56:20.677 回答