【问题标题】:JS Hint - don't make functions within a loopJS 提示 - 不要在循环中创建函数
【发布时间】:2023-08-04 12:35:01
【问题描述】:

我无法绕过 JSHint 的错误消息。这是我正在使用的循环:

for (i = 0; i < Collection.length; i += 4) {
    data.push({
        items : Collection.slice(i, i + 4).map(function(item) {
            return {
                id: item[0],
                title: item[1],
            };
        })
    });
}

【问题讨论】:

标签: javascript jshint


【解决方案1】:

您可以将函数移到循环之外并将对它的引用传递给map

function mapCallback(item) {
    return {
        id : item[0],
        title : item[1],
    };
}
for (i = 0; i < Collection.length; i += 4) {
    data.push({
        items: Collection.slice(i, i + 4).map(mapCallback)
    });
}

或者,您可以使用 JSHint 指令来忽略循环内的函数表达式。只需将其放在相关文件的顶部即可:

/*jshint loopfunc: true */

【讨论】:

  • @Skyrim1 警告的原因是为了避免在异步回调(onclick 或 ajax)中使用 i 时经常遇到的错误。你在这里很安全,你可以用 James 的建议告诉 jshint 保持安静
  • 如果有人碰巧在 SublimeLinter 中使用 Sublime Text,您可以在 Package Settings -> SublimeLinter -> User - Settings 中更改此设置,使用 "jshint_options": { "loopfunc": true }跨度>
  • 如果您使用/*jshint ... */ 注释禁用警告,将注释保留在该循环块内而不是文件顶部是最安全的。这样您就不会意外地在文件的其他部分隐藏未来的问题。
  • /*jshint loopfunc: true */ 无效:/
  • @moala,我将/* jshint loopfunc: true */ 作为for 循环中的第一行,然后警告就消失了。
【解决方案2】:

在循环中声明函数很麻烦,并且可能容易出错。而是定义一次函数,然后进入循环。

var objMaker = function(item) {
    return {
        id : item[0],
        title : item[1],
    };
};

for (i = 0; i < Collection.length; i += 4) {
    data.push({
                  items : Collection.slice(i, i + 4).map(objMaker)
             });
}

【讨论】:

  • 一些评论可能有助于 OP 更好地理解
  • “杂乱无章,可能容易出错”并没有解释什么可能会发生在什么情况下
【解决方案3】:

人们说“在循环中声明函数很麻烦并且可能容易出错”,但循环中的函数是直接在例如 Array.prototype.forEach 方法中指示的。仅仅因为“函数”这个词理论上应该意味着在每个 forEach 调用中重新定义它并不意味着它实际上每次都由 Javascript 引擎定义

外部循环也是如此,因为引擎对指令有“惰性”处理。如果没有真正改变它,他们不会重新定义整个 forEach/Map/etc 构造指令,他们只会为其提供新的参数。

古代 JS 引擎对这些简单的事情以及代码上下文一无所知的时代已经一去不复返了。然而,我们得到了这个古老的警告,它是在函数还不能像 forEachMap 的情况下那样作为参数传递时构思出来的。

【讨论】: