JavaScriptのfor...in文を使うときに気をつけること【Possible iteration over unexpected (custom / inherited) members】
 Author: 水卜

for…in文

JavaScriptでは、for…inを使うとオブジェクトのプロパティ(キー)でループできる。

const expressions = {happy: 1, sad: 2, angry: 3};

for (const expression in expressions) {
  console.log(`${expression}: ${expressions[expression]}`);
}

// expected output:
// "happy: 1"
// "sad: 2"
// "angry: 3"

Possible iteration over unexpected (custom / inherited) members

しかし無邪気に使うと設定によってはintelliJに怒られる。

Possible iteration over unexpected (custom / inherited) members, probably missing hasOwnProperty check

訳すと、「予期せぬメンバーに対する反復(イテレーション)の可能性がある。多分hasOwnpropertyチェックを忘れている。」

対処法

forのなかでhasOwnPropertyをチェックするとよい。
hasOwnPropertyでは継承元のプロパティかどうかをチェックできる。

以下のコードで、expressionsが他のオブジェクトを継承し、予期せぬプロパティを持っていた場合、for…inループでは継承元のプロパティまで拾ってしまう。

そこでhasOwnPropertyを使えば、expressionが直接持っているプロパティだけをループすることができる。

for (const expression in expressions) {
  if (expressions.hasOwnProperty(expression)) {
    console.log(`${expression}: ${expressions[expression]}`)
  }
}

配列では順序性を担保できないので非推奨

for…inは配列にも使えるが、ブラウザによってはループの順序を担保できない。
大人しくfor…ofを使うのが良い。

参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for...in