tslint / codelyzer / ng lint エラー: 「for (... in ...) ステートメントは if ステートメントでフィルタリングする必要があります」 質問する

tslint / codelyzer / ng lint エラー: 「for (... in ...) ステートメントは if ステートメントでフィルタリングする必要があります」 質問する

リントエラーメッセージ:

src/app/detail/edit/edit.component.ts[111, 5]: for (... 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] + ' ';
        }
      }
    }

この lint エラーを修正する方法をご存知ですか?

ベストアンサー1

tslintが指摘している実際の問題を説明するために、for...in ステートメント:

ループは、オブジェクト自体のすべての列挙可能なプロパティと、オブジェクトがコンストラクターのプロトタイプから継承するプロパティを反復処理します (プロトタイプ チェーン内のオブジェクトに近いプロパティは、プロトタイプのプロパティをオーバーライドします)。

つまり、基本的には、オブジェクトのプロトタイプ チェーンから、予期しないプロパティが取得されることになります。

これを解決するには、オブジェクト自体のプロパティのみを反復処理する必要があります。これは 2 つの異なる方法で実行できます (@Maxxx と @Qwertiy の提案による)。

最初の解決策

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

ここでは、オブジェクト.キー()指定されたオブジェクト自身の列挙可能なプロパティの配列を、for...in ループによって提供されるのと同じ順序で返すメソッドです (違いは、for-in ループはプロトタイプ チェーン内のプロパティも列挙することです)。

2番目の解決策

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

このソリューションでは、プロトタイプチェーン内のプロパティを含むオブジェクトのすべてのプロパティを反復処理しますが、オブジェクト.prototype.hasOwnProperty()メソッドは、オブジェクトが指定されたプロパティを独自の(継承されていない)プロパティとして持っているかどうかを示すブール値を返します。これにより、継承されたプロパティが除外されます。

おすすめ記事