ReSharper предупреждение о ClosureOnModifiedVariable - почему? - PullRequest
0 голосов
/ 29 апреля 2020

Итак, я наткнулся на этот код во время обзора:

        var permissions = $("#" + me.map.permissionsGridHtmlId).data("kendoGrid").dataSource.data();
        var data = form.serializeArray();
        for (var i = 0; i < permissions.length; i++) {
            var record = permissions[i].toJSON();
            $.each(record, function (key, value) {
                data.push({
                    // ReSharper disable once ClosureOnModifiedVariable
                    name: "Permissions[" + i + "]." + key,
                    value: value
                });
            });
        }

, и этот комментарий «// ReSharper disable» дал мне паузу. Я попытался разобраться в этом и нашел это - https://www.jetbrains.com/help/resharper/AccessToForEachVariableInClosure.html

Однако я попытался удалить комментарий и затем сделать, как сказано в этой ссылке, создать переменную внутри области видимости, чтобы сохранить значение, но предупреждение не исчезло go.

Более того, несмотря на предупреждение, оно, кажется, ведет себя как задумано - значение «i» изменяется должным образом, и в конце «данные» переменная хранит правильные / ожидаемые значения.

Итак, мой вопрос ... почему ReSharper предупреждает об этом? Есть ли реальная проблема в коде или ошибка в ReSharper? Если первое, как я должен исправить код? Если последнее, верно ли это предупреждение когда-либо (и поэтому мы должны оставить комментарий об отключении), или я должен изменить серьезность проверки, чтобы никогда не показывать это предупреждение?

Обновление

Следующее изменение в коде сделало предупреждение go прочь:

        $.each(permissions, function (i, permission) {
            $.each(permission.toJSON(), function (key, value) {
                data.push({
                    name: "Permissions[" + i + "]." + key,
                    value: value
                });
            });
        });

Я все еще хотел бы знать почему предупреждение появляется, хотя, когда появляются два фрагмента кода действовать одинаково.

1 Ответ

1 голос
/ 06 мая 2020

Доступ к измененному закрытию является проблемой, только если лямбда (параметр функции в вашем случае) будет выполнена после изменения переменной. В вашем случае, $.each должен выполнять лямбду мгновенно, так что это не должно быть проблемой. Но ReSharper не знает, выполнит ли вызываемая функция мгновенно выполненную переданную лямбду или сохранит ее для последующего выполнения, особенно в JavaScript с ее динамической типизацией c. Поэтому он всегда выдает предупреждение.

Обратите внимание, что найденная статья относится к C#, и предложенное исправление действительно только для C#. Вы не можете исправить проблему в JS, используя var i1 = i, потому что переменная i1, объявленная var, будет иметь область действия функции, и вам нужно, чтобы она имела область действия блока. Итак, если вы можете использовать ECMAScript 2015, то вы можете использовать let или const для объявления переменной с областью действия блока, например:

var permissions = $("#" + me.map.permissionsGridHtmlId).data("kendoGrid").dataSource.data();
var data = form.serializeArray();
for (var i = 0; i < permissions.length; i++) {
    var record = permissions[i].toJSON();
    let i1 = i;
    $.each(record, function (key, value) {
        data.push({
            name: "Permissions[" + i1 + "]." + key,
            value: value
        });
    });
}
...