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


229

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

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

この糸くずのエラーを修正する方法はありますか?


多分答えを受け入れますか?
Qwertiy

回答:


241

tslintが指摘している実際の問題説明するために、for ... inステートメントの JavaScriptドキュメントからの引用:

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

したがって、これは基本的に、(オブジェクトのプロトタイプチェーンから)予期しないプロパティを取得することを意味します。

これを解決するには、オブジェクトのプロパティのみを反復処理する必要があります。これは2つの異なる方法で実行できます(@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()メソッドを使用して、オブジェクトが指定されたプロパティを(継承されていない)プロパティとして持つかどうかを示すブール値を返し、継承されたプロパティ。


2
それObject.keysがES5であることに気づきたいです。ES6で唯一のfor-ofループがあります。通常のループで配列を0からその長さまで反復でき、ES5になります。
Qwertiy 2017

4
もう一度注意してください:何らかの理由this.formErrorsでnullの場合は、for...in何もせず、for ... of Object.keys()エラーをスローします。
user3448806 2017年

2番目の解決策に従っていますが、lintメッセージが表示されます。しばらくの間、lintを無効にしました。
raj240

2
どうしてお勧めしませんObject.keys(obj).forEach( key => {...}) か?
Ben Carp

268

@Helzgateの応答を適用するより適切な方法は、「for .. in」を次のように置き換えることです。

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

6
これは問題を解決するだけでなく、のような追加の条件文と比較してボイラープレートコードの量を減らすため、受け入れられる答えになるはずif (this.formErrors.hasOwnProperty(field))です。
Denialos 2017

1
答えに注意してください。コードが壊れる可能性があります。「修正」してからテストしてください。
ZZZ

3
これは、実際にはtslintエラーを削除しません。
HammerN'Songs

7
@ HammerN'Songsはあなたのために変更されていることを確認代わりのため
トム・

ここで同じ問題。これを使用してもエラーは削除されない
llamerr '27

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で、これを「rules」セクションに追加します。

"forin": false

そうでなければ、@ Maxxxは正しい考えを持っています

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

0

このメッセージは、使用を避けることに関するものではないと思いますswitch。代わりに、それをチェックするように求めますhasOwnProperty。背景はここで読むことができます:https//stackoverflow.com/a/16735184/1374488

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.