JsHint(W083):不要在循环内创建函数。 -使用[] .forEach();

问题描述 投票:3回答:1

我收到此错误:

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运算符设置了true / false其他对象的其他属性。

阅读一些文档,我看到的是:

JSHint和ESLint在for,while或做声明正文。

  • 此错误是否合法?
  • 如果是,如何更好地重写这些行?
  • 如果否,如何使用JsHint禁用此特定的错误验证?
javascript jshint eslint
1个回答
7
投票

此错误是否合法?

是的,您正在循环中声明一个函数。最重要的是,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);
  });
});

您也许可以进一步改善它。

© www.soinside.com 2019 - 2024. All rights reserved.