tslint / codelyzer / ng lint错误:“ for(…in…)语句必须使用if语句过滤”


229

棉绒错误消息:

src / app / detail / edit / edit.component.ts [111,5]:对于(... in ...)语句,必须使用if语句进行过滤

代码段(这是一个有效的代码。也可以在angular.io表单验证部分中找到):

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] + ' ';
        }
      }
    }

任何想法如何解决此皮棉错误?


也许接受答案?
Qwertiy

Answers:


241

为了解释 tslint指出的实际问题,引用了for ... in语句的JavaScript文档中的引号:

循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数的原型继承的那些属性(在原型链中更靠近对象的属性将覆盖原型的属性)。

因此,基本上,这意味着您将获得(从对象的原型链中)可能无法获得的属性。

为了解决这个问题,我们只需要迭代对象自身的属性。我们可以通过两种不同的方式来完成此操作(如@Maxxx和@Qwertiy所建议)。

第一个解决方案

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

在这里,我们利用Object.Keys()方法返回给定对象自己的可枚举属性的数组,其顺序与for ... in循环所提供的顺序相同(区别在于for-in循环枚举了in ...原型链)。

第二解决方案

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

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


2
我想注意到Object.keys是ES5。ES6唯一的问题是for-of循环。我们可以在常规循环中从0到其长度迭代数组,这将是ES5。
Qwertiy

4
再一次通知:如果不知何故this.formErrors为null,for...in则什么都不做,而for ... of Object.keys()会抛出错误。
user3448806

我正在遵循第二种解决方案,但仍然看到棉绒消息。暂时禁用皮棉。
raj240 '19

2
你为什么不推荐Object.keys(obj).forEach( key => {...})
本·卡尔

268

应用@Helzgate答复的更整洁的方法可能是将您的'for .. in'替换为

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

6
这应该是可以接受的答案,因为它不仅解决了问题,而且与诸如的其他条件相比,还减少了样板代码的数量if (this.formErrors.hasOwnProperty(field))
Denialos '17

1
请小心答案,这可能会破坏您的代码。在“修复”它之后进行测试。
ZZZ

3
这实际上并没有为我消除tslint错误。
HammerN'Songs,

7
@ HammerN'Songs检查是否已更改为,而不是用于
汤姆

这里同样的问题。使用此错误后,错误仍无法消除
llamerr '18

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

13

使用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] + ' ';
    });
  }
});

2

如果出于您的目的,for(... in ...)的行为是可接受的/必需的,则可以告诉tslint允许它。

在tslint.json中,将其添加到“规则”部分。

"forin": false

否则,@ Maxxx具有正确的想法

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.