実行環境 Node.js 15.2.1

公開日 February 10, 2021, GMT+9

コード例の出力としてconsole.logを使用しています。

使用方法がわからない場合は以下のページを参照してからコード例を確認してください。

console.logの使用方法

このページではfor...in文の解説をしています。
for...in文と構文が似ている、 通常のfor文for...of文ArrayオブジェクトのforEachメソッド については各リンク先ページで解説しているのでそちらを参照してください。

for...in文

注意
for...in文はプロパティへのアクセス順序が任意なので 配列に対しての使用が推奨されていません。 プロパティへのアクセス順序が重要な配列に対しては 通常のfor文for...of文ArrayオブジェクトのforEachメソッド の使用を検討してください。

このページでは豊富な例を用いてJavaScript(js)のfor...in文の使い方を学ぶことができます。

for...in文はオブジェクトに対して「文字列であるすべての列挙可能プロパティ(キー)」に対してループ・繰り返し処理を行います。 この列挙可能プロパティには継承されたプロパティも含まれます。

冒頭でも説明したとおり、for...in文は任意の順番でプロパティにアクセスして処理を行うので、順序が重要な配列などに対して使用することは推奨されていません。

// 記述例

for (const プロパティが代入される変数 in オブジェクト) {
  // 1回のループ中に行う処理
}

出典:for...in文 - MDN web docs

TL;DR

基本

// for...in文はオブジェクトの列挙可能なプロパティに対して繰り返し処理を実行する
const object1 = { a: 'A', b: 'B', c: 'C' };
for (const property in object1) {
  console.log(property, object1[property]);
}
==> a A
==> b B
==> c C





// Arrayオブジェクトの場合(インデックス値がプロパティ)
const array1 = ['js', 'javascript'];
for (const property in array1) {
  console.log(property, array1[property]);
}
==> 0 js
==> 1 javascript





// シンボル(Symbol)型のプロパティは列挙されません
const object2 = { a: 'A', [Symbol('b')]: 'B' };
console.log(object2);
==> { a: 'A', [Symbol(b)]: 'B' }

for (const property in object2) {
  console.log(property, object2[property]);
}
==> a A

追加プロパティがある場合

// 列挙可能なプロパティを追加する(Object)
Object.prototype.fooBarNinja1 = 'FooBarNinja-1';
const object1 = { a: 'A', b: 'B' };
object1.func1 = () => 'func1';
for (const property in object1) {
  console.log(property, object1[property]);
}
==> a A
==> b B
==> func1 [Function (anonymous)]
==> fooBarNinja1 FooBarNinja-1





// 全ての列挙可能なプロパティを表示(Array)
Object.prototype.fooBarNinja1 = 'FooBarNinja-1';
Array.prototype.fooBarNinja2 = 'FooBarNinja-2';
const array1 = [100, 200];
array1.target = 'TARGET';
for (const property in array1) {
  console.log(property, array1[property]);
}
==> 0 100
==> 1 200
==> target TARGET
==> fooBarNinja2 FooBarNinja-2
==> fooBarNinja1 FooBarNinja-1





// 自身のプロパティのみ列挙する(継承したプロパティは除外)
for (const property in array1) {
  if (array1.hasOwnProperty(property)) {
    console.log(property, array1[property]);
  }
}
==> 0 100
==> 1 200
==> target TARGET

for...of文との違い

// 配列の場合
const array1 = ['js', 'JavaScript'];
array1.fooBarNinja = 'FooBarNinja';
// for...in文
for (const element in array1) {
  console.log(element);
}
==> 0
==> 1
==> fooBarNinja

// for...of文
for (const element of array1) {
  console.log(element);
}
==> js
==> JavaScript





// 文字列の場合
const string1 = 'ES6';
// for...in文
for (const element in string1) {
  console.log(element);
}
==> 0
==> 1
==> 2

// for...of文
for (const element of string1) {
  console.log(element);
}
==> E
==> S
==> 6





// オブジェクトの場合
const object1 = { a: 'A', b: 'B' };
// for...in文
for (const element in object1) {
  console.log(element);
}
==> a
==> b

// for...of文
for (const element of object1) {
  console.log(element);
}
==> TypeError: object1 is not iterable

解説

// 記述例

for (const プロパティが代入される変数 in オブジェクト) {
  // 1回のループ中に行う処理
}

出典:for...in文 - MDN web docs

基本

for...in文はオブジェクトに属する各列挙可能プロパティに対してループ処理を実行します。 ループ処理が実行されるプロパティ(キー)は文字列のものだけであり、Symbol型など他の型のプロパティはfor...in文で処理されません。

注意事項として、for...in文を使用したループ処理は、プロパティへのアクセス順序が保証されていないことが挙げられます。 そのため、 配列などの順序が重要な型やオブジェクトに対してはfor...in文の使用は推奨されません。 コード例はあくまで挙動の一例としてください。

// オブジェクトの列挙可能なプロパティに対して繰り返し処理を実行
const object1 = { name: 'Wang', age: 20, nationality: 'USA' };
for (const property in object1) {
  console.log(property, object1[property]);
}
==> name Wang
==> age 20
==> nationality USA





// Arrayオブジェクト(インデックスがプロパティ)
const array1 = [100, 200, 300];
for (const property in array1) {
  console.log(property, array1[property]);
}
==> 0 100
==> 1 200
==> 2 300





// シンボル(Symbol)型のプロパティは列挙されない
const objectWithSymbol2 = { name: 'Wang', [Symbol('age')]: 30, nationality: 'USA' };
console.log(objectWithSymbol2);
==> { name: 'Wang', nationality: 'USA', [Symbol(age)]: 30 }

for (const property in objectWithSymbol2) {
  console.log(property, objectWithSymbol2[property]);
}
==> name Wang
==> nationality USA

追加プロパティがある場合

for...in文は列挙することが可能なプロパティに対して処理を行います。 ここでは継承したプロパティや、後から追加したプロパティがどのように扱われるかの例を挙げます。

コード例では継承したプロパティや、後から追加したプロパティもfor...in文の処理の対象となっていることがわかります。
対象オブジェクト自体のプロパティのみに対して処理を行いたい、継承したプロパティなどに対して処理を行いたくない場合は、 hasOwnPropertyメソッドなどを利用してループ処理内で場合分けを実行してください。

// 列挙可能なプロパティを追加(Object)
Object.prototype.fooBarNinja1 = 'FooBarNinja-1';
const object1 = { name: 'Weng' };
object1.func1 = () => 'func1';
for (const property in object1) {
  console.log(property, object1[property]);
}
==> name Weng
==> func1 [Function (anonymous)]
==> fooBarNinja1 FooBarNinja-1





// 全ての列挙可能なプロパティを表示(Array)
Object.prototype.fooBarNinja1 = 'FooBarNinja-1';
Array.prototype.fooBarNinja2 = 'FooBarNinja-2';
const array1 = ['js', 'javascript'];
array1.target = 'TARGET';
for (const property in array1) {
  console.log(property, array1[property]);
}
==> 0 js
==> 1 javascript
==> target TARGET
==> fooBarNinja2 FooBarNinja-2
==> fooBarNinja1 FooBarNinja-1





// 自身のプロパティのみ列挙(継承したプロパティは除外)
for (const property in array1) {
  if (array1.hasOwnProperty(property)) {
    console.log(property, array1[property]);
  }
}
==> 0 js
==> 1 javascript
==> target TARGET

for...of文との違い

for...in文と構文がよく似ている for...of文 があります。
以下が主な違いであるので、特徴を意識して使い分けてください。

for...in文

「オブジェクト」の「列挙可能な文字列型のプロパティ」に対して「任意の順序」で処理を実行する。

for...of文

「反復可能なオブジェクト」の「プロパティの値」に対して「定義された順序」で処理を実行する。

// 文字列の場合
const string1 = 'js';
// for...in文
for (const element in string1) {
  console.log(element);
}
==> 0
==> 1

// for...of文
for (const element of string1) {
  console.log(element);
}
==> j
==> s





// 配列の場合
const array1 = [100, 200];
array1.fooBarNinja = 'FooBarNinja';
// for...in文
for (const element in array1) {
  console.log(element);
}
==> 0
==> 1
==> fooBarNinja

// for...of文
for (const element of array1) {
  console.log(element);
}
==> 100
==> 200





// オブジェクトの場合
const object1 = { a: 'A', b: 'B' };
// for...in文
for (const element in object1) {
  console.log(element);
}
==> a
==> b

// for...of文
for (const element of object1) {
  console.log(element);
}
==> TypeError: object1 is not iterable

1次情報

for...in - MDN web docs

for...inを使用する理由 - MDN web docs

プロパティの列挙可能性と所有権 - MDN web docs

ループと反復処理 - MDN web docs

for...ofとfor...inとの違い - MDN web docs