We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

for..in 文は、指定したオブジェクトの列挙可能プロパティに対して、順不同で反復処理をします。各プロパティに対して、指定された文を実行できます。

構文

for (variable in object) {... }
variable
反復するごとに、variable に異なるプロパティ名が代入されます。
object
このオブジェクトの列挙可能プロパティに対して反復処理がされます。

説明

for...in ループは列挙可能プロパティに対してのみ反復されます。ArrayObject のようなビルトインのコンストラクタから生成したオブジェクトは、StringindexOf メソッドや ObjecttoString メソッドといった、Objet.prototypeString.prototype から列挙可能でないプロパティを継承しています。このループは、対象オブジェクト自身とそのオブジェクトがプロトタイプから継承しているすべての列挙可能なプロパティを反復します (プロトタイプチェーンで対象オブジェクトに近いプロパティは、親プロトタイプのプロパティを上書きする)。

プロパティの変更や削除

for...in ループは、任意の順序でオブジェクトのプロパティに対して反復します (なぜ繰り返しの見かけの順序に依存できないのかについては、詳細は delete オペレーターを見てください} 。

もしプロパティがある反復で修正されて、その後に訪問されたなら、ループにより公開される値は後の時点での値となります。訪問される前に削除されたプロパティは、それから後には訪問されません。オブジェクトに対する反復が起きている中でそのオブジェクトに追加されたプロパティは、訪問されるかもしれませんし反復から省略されるかもしれません。

一般的に、現在訪問しているプロパティ以外のものに関しては、反復の間はオブジェクトにプロパティを追加、修正、または削除しないのが一番です。追加したプロパティが訪問されるか、(現在のもの以外の)修正したプロパティが修正される前または後に訪問されるか、または削除したプロパティが削除される前に訪問されるかといったことには、何の保証もありません。

配列の繰り返しと for...in

注: for...in はインデックスの順序が重要となる 配列 の繰り返しには使うぺきではありません。

配列のインデックスは単に整数値の名前で列挙できるプロパティであり、そうでないと一般的なオブジェクトのプロパティとして一意になりません。for...in は特定の順序で並べられる保証はありません。for...in ループ文はすべての列挙できるプロパティを返し、その中には非整数型やそれを引き継いだインデックス名があります。

繰り返しの順序が実装依存なため、配列の繰り返しは要素を一貫した順番で参照することになるとは限りません。このため、アクセスの順番が大事となる配列を繰り返す時には、数値のインデックスでの for ループ (か Array.prototype.forEach()for...of ループ) を使った方が良いです。

独自のプロパティだけで繰り返す

オブジェクトに付属するプロパティだけを考えればよい場合、 getOwnPropertyNames() を使うか、 hasOwnProperty() を実行してチェックします(propertyIsEnumerable も使用できます)。または、外部のコードインターフェイスをまったく知らない場合は、チェックメソッドを備えた組み込みの prototypes を継承できます。

次の関数は、オブジェクトとそのオブジェクトの名前を引数として取ります。そして、そのオブジェクトの全プロパティに対して反復し、プロパティ名とその値を一覧にした文字列を返します。

var obj = {a: 1, b: 2, c: 3};
    
for (const prop in obj) {
  console.log(`obj.${prop} = ${obj[prop]}`);
}

// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

次の関数では hasOwnProperty(): の使い方を例示しています。継承されたプロパティは表示されません。

var triangle = {a: 1, b: 2, c: 3};

function ColoredTriangle() {
  this.color = 'red';
}

ColoredTriangle.prototype = triangle;

var obj = new ColoredTriangle();

for (const prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    console.log(`obj.${prop} = ${obj[prop]}`);
  } 
}

// Output:
// "obj.color = red"

仕様

仕様書 策定状況 コメント
ECMAScript Latest Draft (ECMA-262)
for...in statement の定義
ドラフト  
ECMAScript 2015 (6th Edition, ECMA-262)
for...in statement の定義
標準  
ECMAScript 5.1 (ECMA-262)
for...in statement の定義
標準  
ECMAScript 3rd Edition (ECMA-262)
for...in statement の定義
標準  
ECMAScript 1st Edition (ECMA-262)
for...in statement の定義
標準 初期定義

ブラウザ互換性

機能ChromeEdgeFirefoxInternet ExplorerOperaSafari
基本対応 あり あり16 あり あり
機能Android webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
基本対応 あり あり あり4 あり あり あり

互換性: 初期化式

SpiderMonkey 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37) より前では、for...in ループ内の初期化式(i=0) 画可能でした:

var obj = {a:1, b:2, c:3};
for(var i=0 in obj) {
  console.log(obj[i]);
}
// 1
// 2
// 3

この非標準な動作はバージョン 40 以降では無視され、strict mode での SyntaxError ("for-in loop head declarations may not have initializers") エラーが防がれます  (バグ 748550バグ 1164741)。

v8 (Chrome), Chakra (IE/Edge), JSC (WebKit/Safari) といった他のエンジンも同様に非標準のふるまいを削除するよう開発しています。

関連項目

 

ドキュメントのタグと貢献者

タグ: 
このページの貢献者: Uemmra3, ambi, lv7777, mamodayo, teoli, taiyaki32, ethertank, Potappo, Mgjbot, Nanto vi
最終更新者: Uemmra3,