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

Gib*_*boK 3 javascript jshint eslint

我收到此错误:

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));
}
Run Code Online (Sandbox Code Playgroud)

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

阅读一些我看到的文档:

JSHint和ESLint在for,while或do语句体中遇到函数表达式.

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

ssu*_*ube 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);
}
Run Code Online (Sandbox Code Playgroud)

但是,我没有看到你在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);
}
Run Code Online (Sandbox Code Playgroud)

这两个都需要重构你的代码,因为你使用闭包来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));
}
Run Code Online (Sandbox Code Playgroud)

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

rules.data[rule] = !!(meta[prop].data[rule]);
Run Code Online (Sandbox Code Playgroud)

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

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

你或许可以进一步提高.