HOWTO · JavaScript
JavaScript オブジェクトのキーを取得する
このチュートリアルでは、JavaScript でオブジェクトのキーを取得する方法について詳しく説明します。
このページの内容
オブジェクト自身が持つ列挙可能な文字列プロパティ名を配列で取得するには、Object.keys(obj) を使います。各キーを対応する値と組み合わせて扱う場合は、Object.entries(obj) が便利です。どちらのメソッドもオブジェクト自体は変更しません。継承された列挙可能なプロパティも含めてループするには for...in を使い、必要に応じて自身のプロパティだけに絞ります。
Object.keys()でオブジェクトのキーを取得する
Object.keys() は、オブジェクト自身が持つ列挙可能な文字列キーを配列で返します。APIから受け取ったレコードのように、事前にプロパティ名がわからない場合に役立ちます。返される配列に含まれるのは名前だけです。値を読むには obj[key] を使います。オブジェクトに自身の列挙可能な文字列プロパティがなければ、空の配列が返ります。シンボルプロパティは含まれません。
プロパティの順序には規則がありますが、キーを書いた順序と常に同じとは限りません。配列インデックスのキー(0 から 4294967294 までの正規の整数インデックス文字列)が数値の昇順で先に並びます。それ以外の文字列キーは、プロパティが作成された順に続きます。"01" のような文字列は配列インデックスではないため、ほかの文字列キーと同じ順序規則に従います。配列でも同様に、Object.keys() は存在する列挙可能なインデックスキーを文字列として返します。配列の値を返すわけではありません。
次の例を実行します。
const record = { 4: 'pear', 2: 'mango', name: 'fruit', '01': 'label' };
const keys = Object.keys(record);
console.log(keys);
console.log(record[keys[0]]);
console.log(Object.keys(['red', 'blue']));
この例では、数値インデックスのキーがほかの文字列より先に並び、"01" は通常の文字列キーとして扱われます。また、返されたキーを使って値を参照しています。キーを取得しても、record のプロパティの順序や値は書き換わりません。
Object.entries()でオブジェクトのキーと値を取得する
キーと対応する値を次の処理で使う場合は、Object.entries(obj) を使います。[[key, value], ...] のような2要素配列の配列を返します。Object.keys() と同様に、対象になるのはオブジェクト自身が持つ列挙可能な文字列プロパティで、順序も同じです。シンボルは含まれず、値がオブジェクトであっても再帰的にはたどりません。
分割代入を使うと、各ペアを簡潔に処理できます。次の完全な例は、各プロパティについてラベルと値を出力します。コード内のラベルは変更されず、英語のまま表示されます。
const settings = { theme: 'dark', language: 'English' };
for (const [key, value] of Object.entries(settings)) {
console.log(`${key}: ${value}`);
}
名前だけで十分なら Object.keys() を、ループ内で名前と値を一緒に使うなら Object.entries() を選びます。キーがすでにわかっている場合、オブジェクトを列挙する必要はありません。settings.theme または settings['theme'] で値に直接アクセスできます。
for…inでオブジェクトのキーを反復処理する
for...in ループは、列挙可能な文字列プロパティを反復処理します。オブジェクトのプロトタイプを通じて継承されたプロパティも含まれることがあるため、自身のプロパティだけを列挙する Object.keys() とは結果が異なる場合があります。継承プロパティを除外するには、ループ内で Object.hasOwn(obj, key) を使います。このメソッドは最新のJavaScriptで利用できます。古い環境では Object.prototype.hasOwnProperty.call(obj, key) を使います。
const parent = { category: 'fruit' };
const item = Object.create(parent);
item.name = 'mango';
for (const key in item) {
if (Object.hasOwn(item, key)) {
console.log(`${key}: ${item[key]}`);
}
}
ループでは name と継承された category の両方に遭遇する可能性がありますが、自身のプロパティかどうかを確認すると name だけが出力されます。すべての列挙可能なプロパティが必要なら、確認処理を省略します。オブジェクト自身が持つ列挙可能な文字列キーを予測可能な順序で取得するには、通常 Object.keys() が最もわかりやすい方法です。
列挙は浅い処理です。トップレベルのプロパティに別のオブジェクトが入っている場合、キーの一覧に含まれるのはトップレベルのプロパティ名で、その値は入れ子のオブジェクトのままです。入れ子のキーを一覧にするには、その値に対して別途 Object.keys() を呼び出します。再帰的にたどるには、各入れ子のオブジェクトを調べる追加の処理が必要です。必要なプロパティに応じて3つの方法を選びます。名前には Object.keys()、名前と値のペアには Object.entries()、プロトタイプチェーン上のものも含む列挙可能なプロパティには for...in を使います。