for..in 文は、指定したオブジェクトの列挙可能プロパティに対して、順不同で反復処理をします。各プロパティに対して、指定された文を実行できます。
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
構文
for (variable in object) {... }
variable- 反復するごとに、
variableに異なるプロパティ名が代入されます。 object- このオブジェクトの列挙可能プロパティに対して反復処理がされます。
説明
for...in ループは列挙可能プロパティに対してのみ反復されます。Array や Object のようなビルトインのコンストラクタから生成したオブジェクトは、String の indexOf メソッドや Object の toString メソッドといった、Objet.prototype や String.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"
仕様
ブラウザ互換性
| デスクトップ | モバイル | サーバー | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
for...in | Chrome 完全対応 1 | Edge 完全対応 12 | Firefox 完全対応 1 | IE 完全対応 6 | Opera 完全対応 2 | Safari 完全対応 1 | WebView Android 完全対応 1 | Chrome Android 完全対応 18 | Firefox Android 完全対応 4 | Opera Android 完全対応 10.1 | Safari iOS 完全対応 1 | Samsung Internet Android 完全対応 1.0 | nodejs 完全対応 0.1.100 |
凡例
- 完全対応
- 完全対応
互換性: 初期化式
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) といった他のエンジンも同様に非標準のふるまいを削除するよう開発しています。
関連項目
for...of- プロパティ値に対して繰り返す同様の文- for each...in -
for...inに似ていますが、プロパティ名そのものではなく、オブジェクトのプロパティの値に対して反復します。(廃止されました) for- Generator expressions (
or...inを使っている) - Enumerability and ownership of properties
Object.getOwnPropertyNames()Object.prototype.hasOwnProperty()Array.prototype.forEach()