JsHint W083不要在循环中使用函数和jQuery的$ .each()函数

JNY*_*ger 6 javascript jquery loops

我目前正在使用JsHint并且收到警告W083:"不要在循环中创建函数".我从JsLint错误解释中读到了这篇文章,并理解为什么你不应该这样做,这基本上归结为JavaScript的不正常性以及可能被覆盖的变量.

不过,我还在其他一些帖子中读到SO虽然这是一个失礼,但并不总是会导致错误,具体视情况而定.

我特别注意JsHint抱怨的情况是一个使用jQuery $(selector).each()函数的for循环.该函数将函数作为参数.下面是我关注的代码片段.不要担心它实际上做了什么+因为我真的只是以此为例:

for (var i = 0; i < sections.length; i++) {
    disableSectionState[sections[i].name] = {};

    $('.' + sections[i].name).each(function (index, element) {
        var id = $(element).attr('id');
        disableSectionState[sections[i].name][id] = $(element).attr('disabled');
    });

    if (sections[i].isChecked) {
        $('.' + sections[i].name).attr('disabled', 'disabled');
    }
}
Run Code Online (Sandbox Code Playgroud)

从本质上讲,这只是一个for循环中的嵌套for-each循环,所以我不认为这会太危险,但我显然不熟悉js中的所有怪癖.截至目前,一切都在使用此功能正常工作,但我想向社区询问使用jQuery在循环中的每个函数的危险.

为了防止这被标记为欺骗我确实看到了这个问题,但唯一的答案没有详细说明或解释任何内容,并且基于评论它看起来像XY问题无论如何.我更感兴趣的是,为什么它的核心是它本质上是一个嵌套循环.

在循环之外提取和命名此函数真的更安全吗?如果我将循环计数器复制到匿名函数范围内的变量,是否会消除此设计的潜在危险?该函数是否在主for循环之外完全异步执行?

+ 如果您真正感兴趣:此代码用于确定在启用某些选项时是否应在页面加载时禁用某些字段.

ssu*_*ube 12

问题不是each在循环中使用jQuery ,而是反复声明一个函数.这可能导致一些奇怪的闭包问题(该函数在对循环计数器的引用时关闭,它仍然会更新并且可以更改)并且对于不太聪明的VM可能是一个非平凡的性能问题.

所有JSHint都要求你改变是:

function doStuff(index, element) {
  var id = $(element).attr('id');
   disableSectionState[sections[i].name][id] = $(element).attr('disabled');
}

for (var i = 0; i < sections.length; i++) {
  disableSectionState[sections[i].name] = {};

  $('.' + sections[i].name).each(doStuff);

  if (sections[i].isChecked) {
    $('.' + sections[i].name).attr('disabled', 'disabled');
  }
}
Run Code Online (Sandbox Code Playgroud)

当你从一个循环中异步调用某些东西并关闭循环计数器时,大多数危险都来了.举个例子:

for (var i = 0; i < urls.length; ++i) {
  $.ajax(urls[i], {success: function () {
    console.log(urls[i]);
  });
}
Run Code Online (Sandbox Code Playgroud)

您可能会认为它将在请求成功时记录每个URL,但由于i可能length在从服务器返回任何请求之前命中,因此您更有可能重复查看最后一个URL.如果你考虑它是有道理的,但如果你没有密切注意关闭或者有更复杂的回调,它可能是一个微妙的错误.

不在循环中声明函数会强制您显式绑定或传递循环计数器,以及其他变量,并防止这种事情意外地出现.

在一些更天真的实现中,机器实际上也可以在循环的每次迭代中为函数创建闭包范围,以避免在循环内变化的任何潜在奇怪.这可能会导致许多不必要的范围,这会产生性能和内存影响.