因此,我在审查中遇到了以下代码:
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
但是,我试图删除注释,然后按该链接所述进行操作,在作用域内创建一个变量来存储值,但警告并没有消失。
此外,尽管有警告,但它的行为似乎像设计的一样-“ i”的值正确更改,最后,“ data”变量存储了正确/期望的值。
所以,我的问题是...为什么ReSharper为此警告?代码中是否存在实际问题,还是ReSharper中存在错误?如果是前者,我应该如何修复代码?如果是后者,此警告是否正确(因此我们应该留下禁用注释),还是应该更改检查严重性以永不显示此警告?
更新资料
对代码的以下更改使警告消失了:
$.each(permissions, function (i, permission) {
$.each(permission.toJSON(), function (key, value) {
data.push({
name: "Permissions[" + i + "]." + key,
value: value
});
});
});
但是,当两个代码段的行为相同时,我仍然想知道为什么会出现警告。
最佳答案
仅当在修改变量后执行lambda(您的情况下为函数参数)时,才可以访问修改后的闭包。在您的情况下,$.each
应该立即执行lambda,所以这不是问题。但是ReSharper不知道被调用函数是立即执行传递的lambda还是将其存储以供以后执行,尤其是在具有动态类型的JavaScript中。因此,它始终会发出警告。
请注意,您发现的文章涉及C#,并且它建议的修复仅对C#有效。您不能通过使用var i1 = i
来解决JS中的问题,因为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
});
});
}