tslint / codelyzer / ng lint error: "for (... in ...) statements must be filtered with an if statement"

tslint / codelyzer / ng lint error: "for (... in ...) statements must be filtered with an if statement"

Lint 错误消息:

src/app/detail/edit/edit.component.ts[111, 5]: for (... in ...) statements must be filtered with an if statement

代码片段(这是一个工作代码。它也可以在 angular.io form validation section 获得):

for (const field in this.formErrors) {
      // clear previous error message (if any)
      this.formErrors[field] = '';
      const control = form.get(field);

      if (control && control.dirty && !control.valid) {
        const messages = this.validationMessages[field];
        for (const key in control.errors) {
          this.formErrors[field] += messages[key] + ' ';
        }
      }
    }

知道如何修复此 lint 错误吗?

for (const field in this.formErrors) {
  if (this.formErrors.hasOwnProperty(field)) {
for (const key in control.errors) {
  if (control.errors.hasOwnProperty(key)) {

使用Object.keys:

Object.keys(this.formErrors).map(key => {
  this.formErrors[key] = '';
  const control = form.get(key);

  if(control && control.dirty && !control.valid) {
    const messages = this.validationMessages[key];
    Object.keys(control.errors).map(key2 => {
      this.formErrors[key] += messages[key2] + ' ';
    });
  }
});

应用@Helzgate 回复的更简洁的方法可能是用

替换您的'for .. in'
for (const field of Object.keys(this.formErrors)) {

解释 tslint 指出的实际问题,引用自 for...in statement 的 JavaScript 文档:

The loop will iterate over all enumerable properties of the object itself and those the object inherits from its constructor's prototype (properties closer to the object in the prototype chain override prototypes' properties).

所以,基本上这意味着您将获得您可能不希望获得的属性(来自对象的原型链)。

为了解决这个问题,我们只需要遍历对象自身的属性。我们可以通过两种不同的方式来做到这一点(正如@Maxxx 和@Qwertiy 所建议的那样)。

第一个解决方案

for (const field of Object.keys(this.formErrors)) {
    ...
}

这里我们使用 Object.Keys() 方法,该方法 returns 给定对象自身可枚举属性的数组,其顺序与 for...in 循环提供的顺序相同(不同之处在于for-in 循环也枚举原型链中的属性)。

第二种解决方案

for (var field in this.formErrors) {
    if (this.formErrors.hasOwnProperty(field)) {
        ...
    }
}

在此解决方案中,我们迭代所有对象的属性,包括其原型链中的属性,但使用 Object.prototype.hasOwnProperty() 方法,该方法 returns 一个布尔值,指示对象是否具有指定的 属性 作为自己的(非继承的)属性,以过滤掉继承的属性。

我认为这条消息并不是要避免使用 switch。相反,它希望您检查 hasOwnProperty。背景可以在这里阅读:

如果 for(... in ...) 的行为 acceptable/necessary 符合您的目的,您可以告诉 tslint 允许它。

在 tslint.json 中,将其添加到 "rules" 部分。

"forin": false

否则,@Maxxx 对

的想法是正确的
for (const field of Object.keys(this.formErrors)) {