javascript - JsHint W083 不要在循环中创建函数和 jQuery 的 $.each() 函数

标签 javascript jquery loops

我目前正在使用 JsHint 并收到警告 W083:“不要在循环内创建函数”。我从 JsLint Error Explanations 读到这篇文章并理解为什么你不应该这样做,这基本上归结为 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');
    }
}

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

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

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

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

最佳答案

问题不是在循环中使用 jQuery 的 each,而是重复声明一个函数。这可能会导致一些奇怪的关闭问题(该函数关闭对循环计数器的引用,它仍然会更新并可以更改)并且可能是不太聪明的 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');
  }
}

当您从循环中异步调用某些内容并关闭循环计数器时,大多数危险都会出现。举个例子:

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

您可能认为它会在请求成功时记录每个 URL,但是由于 i 可能会在任何请求从服务器返回之前达到 length,所以您更可能会反复看到最后一个 URL。如果您考虑一下,这是有道理的,但如果您没有密切关注闭包或有更复杂的回调,则可能是一个微妙的错误。

不在循环内声明函数会强制您显式绑定(bind)或传递循环计数器以及其他变量,并防止此类事件意外出现。

在一些更天真的实现中,机器实际上还可以在循环的每次迭代中为函数创建一个闭包范围,以避免在循环内更改的变量出现任何潜在的异常。这会导致很多不必要的作用域,从而影响性能和内存。

关于javascript - JsHint W083 不要在循环中创建函数和 jQuery 的 $.each() 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30484517/

相关文章:

c - 返回除数之和的函数,不带余数,C

javascript - 获取元素相对于最顶层窗口的位置的函数

jquery - 如何使用 jquery 将类添加到单元格

Javascript用空字符串替换单引号

javascript - 附加可变 div 大小

jquery - jquery返回404状态的方法

javascript - 如何使用 for 语句和数组确定单击了哪个元素

php - php foreach 循环中的 Jquery 脚本

javascript - 在 firebreath 的 javascript 端创建一个 JSAPIPtr

javascript - jQuery,如果文件输入扩展名是 .pdf 则运行函数