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.defineProperty
でenumerable: false
と設定されたプロパティ名も取得できる点が、Object.keys
との大きな違いです。
Object.defineProperty
とObject.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.getOwnPropertyNames
とObject.keys
を使って、名前を取得してコンソールに出力しています。
確認すると、Object.getOwnPropertyNames
はsecretKey
を含んでいますが、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アプリケーションにおけるオブジェクトの内部構造の調査やメタプログラミングを行いましょう。
コメント