JavaScriptのObject.getOwnPropertyNamesの使い方!プロパティ名を列挙する

JavaScriptのObject.getOwnPropertyNamesメソッドは、指定されたオブジェクトのすべての自身のプロパティ(継承されたプロパティではない)の文字列キー(プロパティ名)を配列として返すために使用されます。

このメソッドの重要な特徴は、プロパティが列挙可能(enumerable)であるかどうかにかかわらず、すべての文字列キーのプロパティ名を返す点です。
これにより、Object.keysでは取得できない、Object.defineProperty() などでenumerable: falseと設定されたプロパティの名前も取得できます。
オブジェクトの完全なプロパティリストを調べたい場合に非常に強力です。

この記事では、Object.getOwnPropertyNamesメソッドの基本的な使い方、引数、戻り値、主要な使用例、そして使用する際の重要な注意点について詳しく解説します。

Object.getOwnPropertyNamesメソッドの基本的な構文

Object.getOwnPropertyNamesメソッドの基本的な構文は以下の通りです。

Object.getOwnPropertyNames(obj)
  • obj: 必須。プロパティ名を取得したいオブジェクトです。

引数1(obj)

  • 必須です。
  • プロパティ名を取得したいオブジェクトを指定します。
  • objがプリミティブ値(文字列、数値、真偽値など)の場合、内部的にオブジェクトに変換されてからプロパティ名が抽出されます。例えば、文字列を渡すと、その文字列のインデックス('0', '1'など)とlengthプロパティ名が返されます。
  • nullまたはundefinedを渡すと、TypeErrorが発生します。

Object.getOwnPropertyNamesの戻り値

指定されたオブジェクトのすべての自身の文字列キーのプロパティ名を含む新しい配列が返されます。
元のオブジェクトは変更されません。

Object.getOwnPropertyNamesメソッドを使ってみる

実際にObject.getOwnPropertyNamesメソッドを使って、

例1:通常のオブジェクトでの使用

シンプルなオブジェクトのすべてのプロパティ名を取得します。

const user = {
  name: 'Alice',
  age: 30,
  city: 'New York'
};

const propNames = Object.getOwnPropertyNames(user);

console.log(propNames); // 出力: [ 'name', 'age', 'city' ]

最初にuserオブジェクトを作成しています。
次にObject.getOwnPropertyNamesを使用してオブジェクトのプロパティ名を取得しました。

出力して確認すると、userオブジェクトのすべての文字列キーのプロパティ名が配列として取得されていることがわかります。

例2:Object.keysとの比較(非列挙可能プロパティを含む場合)

Object.definePropertyenumerable: falseと設定されたプロパティ名も取得できる点が、Object.keysとの大きな違いです。
Object.definePropertyObject.keysのふたつのメソッドを使って比較します。

"use strict";

const product = {
  id: 'P001',
  price: 100
};

// 列挙不可のプロパティを追加
Object.defineProperty(product, 'secretKey', {
  value: 'XYZ789',
  enumerable: false, // 列挙不可に設定
  writable: true,
  configurable: true
});

console.log("--- Object.getOwnPropertyNames() ---");
const allNames = Object.getOwnPropertyNames(product);
console.log(allNames); // 出力: [ 'id', 'price', 'secretKey' ] (secretKeyも含まれる)

console.log("--- Object.keys() ---");
const enumerableNames = Object.keys(product);
console.log(enumerableNames); // 出力: [ 'id', 'price' ] (secretKeyは含まれない)

productオブジェクトを作成して、次の処理で列挙不可のsecretKeyプロパティを作りました。

Object.getOwnPropertyNamesObject.keysを使って、名前を取得してコンソールに出力しています。
確認すると、Object.getOwnPropertyNamessecretKeyを含んでいますが、Object.keysは含んでいません。

このようにObject.getOwnPropertyNamesを使うと、列挙不可のプロパティも確認することができます。

例3:継承されたプロパティは含まれない

Object.getOwnPropertyNamesは、オブジェクト自身のプロパティのみを対象とします。
プロトタイプチェーンを通じて継承されたプロパティは含まれません。

const animal = {
  eats: true
};
const rabbit = Object.create(animal);
rabbit.jumps = true; // rabbit自身のプロパティ

const rabbitNames = Object.getOwnPropertyNames(rabbit);
console.log(rabbitNames); // 出力: [ 'jumps' ] (eatsは含まれない)

const animalNames = Object.getOwnPropertyNames(animal);
console.log(animalNames); // 出力: [ 'eats' ]

eatsプロパティはrabbitからアクセスできますが、それは継承されたプロパティです。
そのためrabbit自身のプロパティ名としては取得されません。

例4:文字列を渡した場合

文字列もオブジェクトのように扱われ、そのインデックスとlengthプロパティが返されます。

const str = "hello";
const strNames = Object.getOwnPropertyNames(str);

console.log(strNames); // 出力: [ '0', '1', '2', '3', '4', 'length' ]

これは、文字列がプリミティブ値でありながら、内部的にはオブジェクトラッパーを持つためです。

Object.getOwnPropertyNamesを使う際の注意点

Object.getOwnPropertyNamesを使う際の注意点です。

自身のプロパティのみを対象とする

最も重要な注意点です。
プロトタイプチェーンを通じてアクセスできる継承されたプロパティの名前は含まれません
あくまでオブジェクト自身が直接持つプロパティのみが対象です。

文字列キーのプロパティのみを対象とする

Symbol型のキーを持つプロパティの名前は返しません。
シンボルプロパティの名前を取得するには、Object.getOwnPropertySymbolsを使用する必要があります。

const objWithSymbol = {
  a: 1,
  [Symbol('b')]: 2
};
console.log(Object.getOwnPropertyNames(objWithSymbol)); // 出力: [ 'a' ]
console.log(Object.getOwnPropertySymbols(objWithSymbol)); // 出力: [ Symbol(b) ]

列挙可能かどうかにかかわらず取得

Object.keysとは異なり、enumerable: false のプロパティも含まれます。
これがこのメソッドの主な利点の一つです。

存在しない場合は空の配列を返す

オブジェクトに自身の文字列キーのプロパティが一つも存在しない場合(例: Object.create(null)で作成されたオブジェクトや空のオブジェクト)、空の配列 [] が返されます。

null または undefined のオブジェクト引数

Object.getOwnPropertyNames(null)Object.getOwnPropertyNames(undefined)を呼び出すと TypeError が発生します。

プロパティの順序

返されるプロパティ名の配列の順序は、for...inループで取得される順序と同じです。
これは、数値キーの場合は昇順、それ以外の文字列キーは定義順(またはエンジン依存)になります。

まとめ

JavaScriptのObject.getOwnPropertyNamesメソッドは、オブジェクトのすべての自身の文字列キーのプロパティ名(列挙可能かどうかにかかわらず)を取得するための強力なツールです。
Object.keysでは見えない隠されたプロパティの名前も調べたい場合に非常に便利です。

自身のプロパティのみを対象とすること、シンボルキーは含まれないこと、そしてObject.keysとの使い分けを理解して使用することが不可欠です。
これらのポイントを踏まえ、Object.getOwnPropertyNamesを効果的に活用し、JavaScriptアプリケーションにおけるオブジェクトの内部構造の調査やメタプログラミングを行いましょう。

コメント