【问题标题】:JsHint (W083): Don't make functions within a loop. - Using [].forEach();JsHint (W083):不要在循环中创建函数。 - 使用 [].forEach();
【发布时间】:2015-09-17 09:10:29
【问题描述】:

我收到此错误:

JsHint (W083):不要在循环中创建函数。

使用以下代码时:

for (var prop in cmd.properties) {
  Object.keys(meta[prop].data).forEach(function (rule) {
    rules.data[rule] = meta[prop].data[rule] ? true : false;
  }.bind(this));
}

基本上,我循环遍历对象 meta[prop].data 的属性,对于每个属性,我使用 ternary 运算符设置其他对象属性的真/假。

阅读我看到的一些文档:

JSHint 和 ESLint 在 for、while 或 do 语句体。

  • 这个错误合法吗?
  • 如果是,如何更好地重写这些行?
  • 如果否,如何使用 JsHint 禁用此特定错误验证?

【问题讨论】:

  • 你确定这段代码不在循环内吗?
  • @Juhana 感谢您的编辑,我已经对我原来的问题进行了编辑。
  • 嗯,好的,在编辑之后很明显这是一个合法的错误,因为你实际上是在循环中创建一个函数。
  • 不确定,能否请您在修改后的版本中发布答案?非常感谢,谢谢!
  • 你可以再用forEach来代替for循环,那bind(this)有什么用呢? (因为您不在函数中使用this

标签: javascript jshint eslint


【解决方案1】:

这个错误合法吗?

是的,您在循环中声明了一个函数。最重要的是,bind 可能非常昂贵,因为它每次都必须创建一个新的词法作用域并返回一个附加到该作用域的“新”函数。

如果是,如何更好地重写这些行?

如果可以,在循环之前声明函数并绑定一次或使用简单的闭包来避免显式绑定调用:

var scope = this;
var ruleFunc = function (rule) {
  rules.data[rule] = meta[prop].data[rule] ? true : false;
}

for (var prop in cmd.properties) {
  Object.keys(meta[prop].data).forEach(ruleFunc);
}

不过,我看不到您在函数中使用this 的位置,因此您可以将其完全删除:

var ruleFunc = function (rule) {
  rules.data[rule] = meta[prop].data[rule] ? true : false;
}

for (var prop in cmd.properties) {
  Object.keys(meta[prop].data).forEach(ruleFunc);
}

这两个都需要重构代码,因为您使用闭包从循环中获取prop 变量。您可以使用 bind 来解决这个问题,但会影响性能:

var ruleFunc = function (prop, rule) {
  rules.data[rule] = meta[prop].data[rule] ? true : false;
}

for (var prop in cmd.properties) {
  Object.keys(meta[prop].data).forEach(ruleFunc.bind(this, prop));
}

您还使用条件返回 true/false,这是一种常见的气味。您通常希望将其转换为布尔值,!! 是惯用的 JS 方式:

rules.data[rule] = !!(meta[prop].data[rule]);

如果可以的话,避免 for ... in 循环通常会让你的生活变得更好,所以你可能也想重构它:

Object.keys(cmd.properties).forEach(function (prop) {
  Object.keys(meta[prop].data).forEach(function (rule) {
    rules.data[rule] = !!(meta[prop].data);
  });
});

您也许还可以进一步改进。

【讨论】:

  • “避免for ... in 循环通常会让你的生活更美好” - 这是一个有趣的评论,因为关于可能问题的警告(如果我理解正确的原因,不应该是完全没有问题,可以安全地忽略)只有因为避免了for ... in循环(对于内部循环),有利于调用forEach
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2012-10-05
  • 2012-05-14
相关资源
最近更新 更多