導入
JavaScriptで開発をしていると、「オブジェクトにどんなプロパティがあるのか知りたい」という場面によく遭遇します。通常、Object.keys()を使えばプロパティを取得できますが、実はそれだけでは取得できない「隠れたプロパティ」が存在することをご存知でしょうか。Object.getOwnPropertyNamesは、列挙可能かどうかにかかわらず、オブジェクト自身が持つすべてのプロパティ名を取得できる強力なメソッドです。デバッグやライブラリ開発時に、オブジェクトの構造を正確に把握するための必須知識です。
基礎知識
JavaScriptのオブジェクトには「列挙可能(Enumerable)」なプロパティと「列挙不可(Non-enumerable)」なプロパティがあります。Object.keys()やfor…inループは、主に「列挙可能なプロパティ」のみを対象とします。一方、Object.getOwnPropertyNamesは、その名前の通り、オブジェクト自身(継承したものを除く)に定義されたすべてのプロパティ名(Symbolを除く)を配列として返します。これにより、隠された設定値や内部状態の確認が可能になります。
実装/解決策
使い方は非常にシンプルです。引数に調べたいオブジェクトを渡すだけで、そのオブジェクトの全プロパティ名が格納された配列が返ってきます。特に、Object.definePropertyを使って意図的に列挙不可に設定されたプロパティを調査する際に真価を発揮します。
サンプルプログラム
以下のコードは、通常のプロパティと、あえて列挙不可に設定したプロパティを比較して取得する例です。
const user = {
name: 'Tanaka',
age: 25
};
// 'role'プロパティを列挙不可(enumerable: false)として追加
Object.defineProperty(user, 'role', {
value: 'admin',
enumerable: false
});
// 1. Object.keysの場合(列挙可能なものだけ)
console.log('Keys:', Object.keys(user));
// 出力: ["name", "age"]
// 2. Object.getOwnPropertyNamesの場合(すべて取得)
const allProps = Object.getOwnPropertyNames(user);
console.log('All Properties:', allProps);
// 出力: ["name", "age", "role"]
// プロパティの中身を確認するループ
allProps.forEach((prop) => {
console.log(`${prop} の値は ${user[prop]} です`);
});
応用・注意点
実務で使う際の注意点が2つあります。1つ目は、Symbolプロパティです。Object.getOwnPropertyNamesは「文字列」のプロパティ名しか取得できません。Symbolで定義されたプロパティも調べたい場合は、別途 Object.getOwnPropertySymbols() を使用する必要があります。2つ目は、継承したプロパティは対象外であるという点です。プロトタイプチェーン上のプロパティまで含めて調査したい場合は、再帰的にgetPrototypeOfを呼び出すようなロジックが必要になります。これらを意識することで、より深いデバッグや柔軟なデータ操作が可能になります。