【问题标题】:tslint / codelyzer / ng lint error: "for (... in ...) statements must be filtered with an if statement"tslint / codelyzer / ng lint 错误:“for (... in ...) 语句必须使用 if 语句过滤”
【发布时间】:2017-04-07 19:32:55
【问题描述】:

Lint 错误信息:

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

代码 sn-p(这是一个工作代码。也可以在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 错误吗?

【问题讨论】:

  • 可以接受答案吗?

标签: angular angular2-forms angular-cli tslint


【解决方案1】:
for (const field in this.formErrors) {
  if (this.formErrors.hasOwnProperty(field)) {
for (const key in control.errors) {
  if (control.errors.hasOwnProperty(key)) {

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      应用@Helzgate 回复的一种更简洁的方法可能是将您的“for .. in”替换为

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

      【讨论】:

      • 这应该是公认的答案,因为它不仅解决了问题,而且与 if (this.formErrors.hasOwnProperty(field)) 等附加条件相比,它还减少了样板代码的数量。
      • 小心回答,它可能会破坏您的代码。在“修复”它之后进行测试。
      • 这实际上并没有为我消除 tslint 错误。
      • @HammerN'Songs 检查您是否更改为 for of 而不是 for in
      • 这里有同样的问题。使用this后错误未消除
      【解决方案4】:

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

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

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

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

      第一个解决方案

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

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

      第二种解决方案

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

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

      【讨论】:

      • 我想注意到Object.keys 是 ES5。来自 ES6 的唯一东西是 for-of 循​​环。我们可以在通常的循环中从 0 到它的长度迭代数组,它将是 ES5。
      • 再次注意:如果this.formErrors 为空,for...in 什么也不做,而for ... of Object.keys() 会抛出错误。
      • 我正在遵循第二种解决方案,但我仍然看到 lint 消息。暂时禁用 lint。
      • 为什么不推荐Object.keys(obj).forEach( key => {...}) ?
      • @BenCarp - 在异步函数中运行时会出现严重问题,因此,至少对我而言,因为 ... in/of ... 被认为更优越。见:stackoverflow.com/questions/37576685/…
      【解决方案5】:

      我认为这条信息并不是要避免使用switch。相反,它希望您检查hasOwnProperty。背景可以在这里阅读:https://stackoverflow.com/a/16735184/1374488

      【讨论】:

        【解决方案6】:

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

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

        "forin": false
        

        否则,@Maxxx 的想法是正确的

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

        【讨论】:

        • 编辑 tslint.json....快速、简单且效果很好。很好的答案!
        猜你喜欢
        • 2017-10-31
        • 2017-08-14
        • 2017-04-28
        • 2012-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-03
        相关资源
        最近更新 更多